SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

【php】fgetcsv() がうまくいかない

fgetcsv()便利ですね。愛用してます。

fgetcsv()なしでCSV取り込み処理を作成しろといわれると、ちょっと憂鬱になります。

そんなfgetcsv()君がバックスラッシュ(円マーク)を含むCSVをうまく取り込めない現象に遭遇しました。

Excel方式のCSVには、エスケープ文字などないのですが、もしやバックスラッシュをエスケープ文字として取り扱ってしまうのではないかと考え、オプションで何か指定できないかマニュアルを見に行ってみると、

array fgetcsv  ( resource $handle  [, int $length  [, string $delimiter  [, string $enclosure  [, string $escape  ]]]] )

引数は先頭から順に、ファイルポインタ、CSV1行の最大長、区切り文字(デフォルトはカンマ)、囲み文字(デフォルトはダブルクォーテーション)、エスケープ文字(デフォルトはバックスラッシュ)。

デフォルトでバックスラッシュはエスケープ文字だそうです。

ではこうしてみましょう。

fgetcsv($fp, 0, ',', '"','');

実行すると、

Warning: fgetcsv() expects at most 4 parameters, 5 given in xxxx.php on line xxx

なんで!?

→ マニュアルをよく見ましょう。
“変更履歴”に、「php5.3.0」で「escape パラメータが追加されました。」と書いてあります。

今まで、強制的にバックスラッシュはエスケープ文字として扱われていたということでしょうか。
とにかく、第5引数を使いたかったら、最新バージョンじゃなきゃダメなようです。

php5.3.0環境でやってみるとうまくいきましたが、この問題に遭遇していて、phpバージョンアップは難しい環境もあると思います。

今回はCSV取り込みの問題にphpのバージョンアップで対応しましたが、次回、別手段もご紹介します。

ちなみに、fgetcsv()でうまくCSVが取り込めないときは、以下の点も要チェックです。

  1. CSVをShift_jisのまま取り込もうとしている。→いったんUTF-8にするのがオススメ。
  2. やたらと長い行がないか。第2引数 CSVの1行の最大長に引っかかっている行はないか。

関連するメモ

コメント(1)

【php】fgetcsv()の基本作法 at softelメモ 2010年3月9日 22:13

[…] こんなエスケープ文字がらみの問題がとても稀に発生します。データの絶妙な位置にバックスラッシュがあるときだけの問題です。 […]