fgetcsvで処理したCSVデータが文字化けする時の対処

以下、備忘録。

CSVファイルを開き、fgetcsvで取得したデータを表示してみると見たことのない文字化けが・・・。何か規則があるか眺めてみたけど、よう分からん。大まかには文字列の先頭から数文字が化けてるみたいだけど、中には全く表示されてない物もある状態。

「あいうえお」→「Oうえお」とか「かきくけこ」→「_けこ」とか意味不明(化け方は適当です)

fgetcsvはロケール設定を考慮すると言うことなので、

setlocale(LC_ALL, 'ja_JP');

としてみると、直った!!と思ったら、完全に直ってない・・・。
一部だけ化けるとか、完全に直らないとか、どういうことだよ・・・。

色々調べてみるとPHP5のバグらしい。

CSVの文字コードをUTF-8にするのも手みたいだけど、エクセルで再編集することを考えると面倒なのでボツ。シンプルなCSVなので、explodeで切り分け直しても良さそうなんですけど、yossyさん作の関数でバッチリ解決しました。以下の関数の設定を書けば、fgetcsvの代わりにfgetcsv_regを使うだけですべて解決。う~んすばらし。


function fgetcsv_reg (&$handle, $length = null, $d = ‘,’, $e = ‘”‘) {
$d = preg_quote($d);
$e = preg_quote($e);
$_line = “”;
while ($eof != true) {
$_line .= (empty($length) ? fgets($handle) : fgets($handle, $length));
$itemcnt = preg_match_all(‘/’.$e.’/’, $_line, $dummy);
if ($itemcnt % 2 == 0) $eof = true;
}
$_csv_line = preg_replace(‘/(?:\r\n|[\r\n])?$/’, $d, trim($_line));
$_csv_pattern = ‘/(‘.$e.'[^’.$e.’]*(?:’.$e.$e.'[^’.$e.’]*)*’.$e.’|[^’.$d.’]*)’.$d.’/’;
preg_match_all($_csv_pattern, $_csv_line, $_csv_matches);
$_csv_data = $_csv_matches[1];
for($_csv_i=0;$_csv_iPHP5でfgetcsvが正常に動作しない

2010年7月20日追記
上記のソースで表示上は問題ないのですが、サーバーの方でエラーを吐くので若干修正しました。5行目に変数の定義を追加しただけです。
6行目もwhile (($eof != true) and !feof($handle)) {に変えるといいかも。


function fgetcsv_reg (&$handle, $length = null, $d = ‘,’, $e = ‘”‘) {
$d = preg_quote($d);
$e = preg_quote($e);
$_line = “”;
$eof = false; //ココを追加
while ($eof != true) {
$_line .= (empty($length) ? fgets($handle) : fgets($handle, $length));
$itemcnt = preg_match_all(‘/’.$e.’/’, $_line, $dummy);
if ($itemcnt % 2 == 0) $eof = true;
}
$_csv_line = preg_replace(‘/(?:\r\n|[\r\n])?$/’, $d, trim($_line));
$_csv_pattern = ‘/(‘.$e.'[^’.$e.’]*(?:’.$e.$e.'[^’.$e.’]*)*’.$e.’|[^’.$d.’]*)’.$d.’/’;
preg_match_all($_csv_pattern, $_csv_line, $_csv_matches);
$_csv_data = $_csv_matches[1];
for($_csv_i=0;$_csv_i

コメントを残す

メールアドレスが公開されることはありません。