2010年12月21日火曜日

fgetcsv で文字化け!

「文字化け」

そこはかとなく初心者風味ですね!
それはおいといて、状況説明を。

とあるプロジェクトでCSVをDBに取り込む処理を作る必要が出てきました。
このプロジェクトは、結構昔から動いているシステムにプラグイン的に機能を追加していくような雰囲気のものなんですが、古いだけあって、システムの基幹部分が EUC-JP で組まれている。
で、インポートしたいのはご多分にもれず、Excelから吐き出した Shift_JISのCSV。
CSVの項目内に、「ダブルクオートされたコンマ区切りのデータ列」が含まれるから困ったもんで。
オイラ、基本的にPHPの fgetcsv関数を信用してないもんで、いつもなら fgets してから explodeなりpreg_split なりするんだけど、この状況では、単純な正規表現では切り分けられない。
頑張れば組めそうだけど、そんな目に見えないところに力を注いでる時間もない、ってんで、渋々 fgetcsv関数を使う事に決めたわけですよ、奥さん。
最初はうまくいってるように見えましたよ。最初は。
でも、いろんなデータをインポートしてみたら、ときどきエラーが出ちゃうのね。
なんだ?ってんで確認してみたら、

"パッソ","セッテ","クラウン"

てな感じの行を取り込んだ配列をダンプしたら
array(3) {
[0]=>
string(15) "パッソ",セッテ""
[1]=>
string(8) "クラウン"
}

だってさ。
つまりこういう事だ。
「ソ」ってShift_JISの文字化けトラブルナンバー1の文字なのはご存じのとおり。
で、「ソ"」っていう並びをfgetcsvが取り込もうとした時に、「ソ\"」って変換しちゃったもんだから、次のフィールドまで含めて1つのデータだと勘違いしちゃった感じですね。

結論。

やっぱ fgetcsv は使えねぇ!!

$in = fopen($srcFile, "r");
$out = fopen($dstFile, "w");
while(!feof($in)) {
fputs($out, mb_convert_encoding(fgets($in), "EUC-JP", "SJIS"));
}
fclose($out);
fclose($in);
$fp = fopen($dstFile, "r");
while(!feof($fp)) {
$csv = fgetcsv($fp);
:
:
}
fclose($fp);

ま、結局使うんだけどね。


そんな日。