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コマンドとかでいいのかなーっと。