Windows版PHP(xampp) の fgetcsv() が、php-5.6 と php-7.1 で挙動が変わったことがわかった。
たぶん php-7.0 から。
fgetcsv() はlocaleに依存する関数なので、
UTF8のCSVを読み込むなら ja_JP.UTF-8 を指定する必要があるとマニュアルにもあるのだけど、
Windowsではそもそも UTF-8 ロケールを指定できない。
php-5.6 では特に何も指定せず、デフォルトの Japanese_Japan.932 のままでもUTF8のファイルを読み込めていた・・たぶん。
手元の開発環境でしかないから、テストケースが少なかった可能性はあるけども。
ともかく挙動は変わっている。
php7以降では、Windowsの場合は C ロケールを設定する必要がある模様。
挙動が違う例
<?php $strCsv = '"サーロイン","カルビ","リブロース"'; $fp = fopen('php://memory', 'wb'); fputs($fp, $strCsv); rewind($fp); $arrCsv = fgetcsv($fp); fclose($fp); var_dump($arrCsv);
実行結果(php-5.6.8 xampp)
array(3) {
[0] =>
string(15) "サーロイン"
[1] =>
string(9) "カルビ"
[2] =>
string(15) "リブロース"
}
実行結果(php-7.1.1 xampp)
array(2) {
[0] =>
string(15) "サーロイン"
[1] =>
string(27) "カルビ",リブロース""
}
対応策
UTF8 ロケールがないからどうしようと思ったけど、C ロケールにしたらうまくいった模様。
テストケースはこの3枚の肉だけだけども。
<?php // php7だとこれが必要ぽい if(0 === strpos(PHP_OS, 'WIN')) { setlocale(LC_CTYPE, 'C'); } var_dump(setlocale(LC_ALL, 0)); $strCsv = '"サーロイン","カルビ","リブロース"'; $fp = fopen('php://memory', 'wb'); fputs($fp, $strCsv); rewind($fp); $arrCsv = fgetcsv($fp); fclose($fp); var_dump($arrCsv);
| LC_CTYPE | php5.6 | php7.1 |
|---|---|---|
| Japanese_Japan.932 (default) | ○ | × |
| C | ○ | ○ |