なぜPHPのfgetcsv()はロカール依存という糞仕様なのか

前から言われてる、これ。

(id:hnw さんも、もしかしたらこれは私が実装したということを知っていて自粛してるのかもしれないけど、そういう気遣いは不要です!)

まあつまりですね、もともとfgetcsv()は「\」(0x5c) で次の文字をエスケープできるという割と不便な仕様になっていて、Shift_JISのようなエンコーディングは利用に難ありだったわけで。

で、一応 Shift_JIS が通らないという苦情は来ていて (特に Windows 版で) 、でも標準関数だから mbstring への依存を作るわけにいかない。というわけで C99 になっちゃうんだけど mbrlen(3) (か mblen(3)) を使うということにしたので、結果的にロカールに依存するということになったというわけですよ。

なので、Shift_JIS 使いたければ、libc の設定で利用可能ロカールの一覧に Shift_JIS を含めて、setlocale(LC_CTYPE, "ja_JP.Shift_JIS"); などとするのがある意味理想的といえば理想的です。

どうしても 4.x 系の挙動が欲しいなら

<?php
setlocale(LC_CTYPE, "C");
?>

とでもするといいかも (コマンドラインから起動した場合は setlocale(LC_ALL, "") しない限り "C" ロカールになっているはず)。ただし "C" ロカールでは portable characters 以外での標準関数の挙動は未定義なので、libcによってはうまく動かないかも。


…とまあ、こうやって、糞の上に糞が塗られていたわけです。