PHPのfgetcsvの欠点??特定の文字だけうまく読み込めない
ぎゅう
あれ?
特定の文字だけ\”,が出てきて、エスケープされている!!
カラムが読み込めていない….。
目次
特定の文字だけバックスラッシュが出現する
特定の文字のときだけ、\
バックスラッシュが出現し、,
をエスケープされてしまいます。
そうなると、1行4カラムのはずなのに、途中の行だけ3カラムしか読み込まれない問題が生まれます。
つまり、データがズレます。
こうなると、一部マスタデータが使えないので、問題になります。
このバックスラッシュが出現する問題を5c問題と言います。
5C問題とは「ソ」「表」「十」「予」などSJISの文字の2バイト目が「5C」になる文字が、fgetcsvなどの処理機に与えられたとき、それが文字の一部としてでなく、ASCIIのバックスラッシュ(5C)と判断してしまい、エスケープ文字として解釈される問題を言う。
https://qol-kk.com/wp2/blog/2020/09/10/post-1979/
引き起こす漢字は他にもあります。
銀行のマスタデータだと、伊予銀行の予
で5C問題が発生します。
他にも店名に十
がつくお店もあります。
パッと見ても気付けないけど、
調べてみると結構あるぞ
どうやって、対処しようか?
5c問題をどう回避すればいいのか?
結論
結論、CSVのカラムを読み込む前にutf-8
にファイルごと変換します。
$contents = file_get_contents($csv);
$utf8Contents = mb_convert_encoding($contents, 'UTF-8', 'ASCII,JIS,UTF-8,SJIS-win');
5C問題はSJISの状態で発生するので、読み込む前にUTF-8に変換してしまえば問題ありません。
よくある5C問題が発生する例
foreach ($row as $index => $str) {
$row[$index] = mb_convert_encoding($str, 'UTF-8', "sjis-win");
}
または
$fp = fopen('sjis.csv', 'r');
while ($row = fgetcsv($fp) !== false) {
// fgetcsvで読み取った後に、文字コードを変換している
mb_convert_variables('UTF-8', 'SJIS-win', $row);
}
fclose($fp);
ほんと些細な差ですよね
行ごとにコンバートせずに、ファイルそのものをコンバートするようにしましょう😊
コメント