Hatena::ブログ(Diary)

130単位

2011-04-10

Excel用のCSV(SJIS)をPHP(UTF-8)で読み込む

Excelで作成したCSVファイルは文字コードがShift-JISであるため、UTF-8に設定してあるPHPで扱うには工夫が必要です。その取り扱い方について調べて、ベンチマークをとってみました。

CSVを配列にする関数4通り

テンポラリファイル作成してfgetcsv()
<?php
function by_tmpfile($file) {
	$ret = array();

	$buf = mb_convert_encoding(file_get_contents($file), 'utf-8', 'sjis-win');
	$fp = tmpfile();
	fwrite($fp, $buf);
	rewind($fp);
	while($line = fgetcsv($fp)) {
		$ret[] = $line;
	}
	fclose($fp);

	return $ret;
}
ロケール設定してfgetcsv()
<?php
setlocale(LC_ALL, 'ja_JP.SJIS');
function by_locale($file) {
	$ret = array();

	$fp = fopen($file, 'r');
	while ($line = fgetcsv($fp)) {
		mb_convert_variables('utf-8', 'sjis-win', $line);
		$ret[] = $line;
	}
	fclose($fp);

	return $ret;
}

str_getcsv()
<?php
function by_str_getcsv($file) {
	$ret = array();

	$buf = mb_convert_encoding(file_get_contents($file), 'utf-8', 'sjis-win');
	$lines = str_getcsv($buf, "\r\n");
	foreach ($lines as $line) {
		$ret[] = str_getcsv($line);
	}

	return $ret;
}
  • PHP5.3以上必要
  • 行単位に分割してからstr_getcsv()を呼ぶ
  • Excelのセル内改行はLFなため、CRLFの"\r\n"で分割可能
  • 参考
<?php
function by_str_getcsv_explode($file) {
	$ret = array();

	$buf = mb_convert_encoding(file_get_contents($file), 'utf-8', 'sjis-win');
	$lines = explode("\r\n", $buf);
	array_pop($lines);
	foreach ($lines as $line) {
		$ret[] = str_getcsv($line);
	}

	return $ret;
}
  • explode()版
  • 末尾の改行で分割された行を無視するためarray_pop()している

ベンチマーク

環境
結果
functiontimememory_peak_usage
by_tmpfile12.437s721848
by_locale6.335s719456
by_str_getcsv8.217s726208
by_str_getcsv_explode5.405s726216

平均値ではありませんが再試行しても微量な差です

まとめ

途中Twitterにてアドバイスいただきました@さんありがとうございました!


4774144371
パーフェクトPHP (PERFECT SERIES 3)

関連記事

毘政毘政 2014/01/26 21:25 お尋ねします。
ロケール設定してfgetcsv()のロケールは、”setlocale(LC_ALL, 'ja_JP.UTF-8');”でなくて、良いのですか?

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

リンク元