fgetcsv と ロケール
お勉強してて、軽くハマったのでメモ
fgetcsv ってなんぞ
要約すると
csv形式のファイルをfgets()みたいに取得するよ!
じゃあ fgets() でいいんじゃね?
fgets() に動作は似ていますが、 fgetcsv() は行を CSV フォーマットのフィールドとして読込み処理を行い、 読み込んだフィールドを含む配列を返すという違いがあります。
配列で返してくれるところがミソと。
ハマり箇所
fgetcsv() でファイルを読み込んで、読み込んだ配列を foreach() で回して表示させると日本語が表示されない。
ソースはこんな感じ
csvファイル読み込み
public function getMessageData() { $dataFilePath = "./hogehoge.dat"; // ファイルよりCSVデータ取得 $fp = fopen($dataFilePath, 'r'); $data = array(); while ($row = fgetcsv($fp)) { $data[] = $row; } fclose($fp); return $data; }
呼び出し
// メッセージデータ取得、表示 $data = getMessageData(); // メッセージデータをもとに表のHTML生成 foreach ($data as $row) { echo '<tr>'; echo sprintf('<td>%s<td>', $row[0]); echo sprintf('<td>%s<td>', $row[1]); echo sprintf('<td>%s<td>', $row[2]); echo '</tr>';
csvファイル
1,てすと名前,テストめっせじ
実行した結果
1 空白 空白
と、テスト名前とテストめっせじが表示されない。
原因
注意:
この関数はロケール設定を考慮します。
もし LANG が例えば en_US.UTF-8 の場合、 ファイル中の 1 バイトエンコーディングは間違って読み込まれます。
文字コード。おまえか。
対策
// メッセージデータ取得 public function getMessageData() { setlocale(LC_ALL, 'ja_JP.UTF-8'); // ファイルよりCSVデータ取得 $fp = fopen($this->dataFilePath, 'r'); $data = array(); while ($row = fgetcsv($fp)) { $data[] = $row; } fclose($fp); return $data; }
こいつを追加したら、無事日本語も表示されました。
setlocale(LC_ALL, 'ja_JP.UTF-8');
地味に、ファイルの文字コードを調べるのがわからない。
nfkコマンドとかでいいのかなーっと。