fgetcsv()関数について

2007年12月 5日 11:37 fgetcsv()関数について

本日も旧ブログからの転載です。

PHP の fgetcsv 関数に関するエントリーですが、2年半ほど前に書いたものなので、現状の PHP のバージョンではまた色々と違ってくるかもしれません。

もう fgetcsv 関数は全然使わなくなったので、現状でどういう挙動なのかはさっぱり知りませんが、まあ何かの参考になれば。


データ群を、特定の文字を区切りとしてcsv形式で保存し、phpから取り出すことはよくあると思うのですが、そういう時に便利なのが fgetcsv()関数。
が、この関数はphpのバージョンによって微妙に挙動が違ったりするようなので、適当に使ってると別のサーバーで同じスクリプトを使うと痛い目に遭ったりします。

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

fgets()に動作は似ていますが、 fgetcsv()は行をCSVフォーマッ トのフィールドとして読込み処理を行い、読み込んだフィールドを含む 配列を返すという違いがあります。フィールドのデリミタは、オプショ ンの3番目のパラメータで別のデリミタを指定した場合を除きカンマです。 また、オプションの enclosure (フィールド囲い子) パラメータは、別の文字を4番目のパラメータで 指定しない限り、デフォルトではダブルクォーテーショーンマークとなります。 enclosuredelimiter はそれぞれ1文字に限られており、もし1文字を超える文字列が指定された場合は、 最初の文字だけが使われます。

日本PHPユーザ会マニュアル内「fgetcsv」の頁より。

つまり、ファイルを一行ずつ読み込んで、特定の区切り文字でsplitして、という作業をこの関数が一発で済ましてくれるわけです。

ここでまず重要なのは最後の「enclosuredelimiter はそれぞれ1文字に限られており、もし1文字を超える文字列が指定された場合は、 最初の文字だけが使われます。」という一文。
フィールドの区切りは1文字に限定されますので、perlのcgiなんかでよく使われていた(orる)「<>」を区切りに使う手法は使えません。
カンマ「,」区切りとか、タブ「\t」区切りとかを使いましょう。
「もし1文字を超える文字列が指定された場合は、 最初の文字だけが使われます。」とありますが、「\t」を「\」と「t」の二文字として判断したりはしません。

次に、「enclosure (フィールド囲い子) パラメータは、別の文字を4番目のパラメータで 指定しない限り、デフォルトではダブルクォーテーショーンマークとなります。」という一文。
私はマニュアルを良く読まずに「enclosureを指定しなければ、フィールドの囲い子は「ない」として扱われると思いこんでいたため(そしてうちのサーバーではそれで問題なく動いてしまっていた)、そのスクリプトを他所様のサーバーで動かすと大量に文字化けが発生してしまいました。

この件の場合、fgetcsv()を使っている箇所は何も弄らずに、データ自体の各フィールドをダブルクォーテーションで括るようにしたところ、無事に意図通りの挙動をするようになりました。

とは言え、enclosureを指定せず、データの囲い子がない状態でもうちのサーバーだとちゃんと区切ってくれたと言うことは、逆にenclosureをちゃんと指定しておかないとどういう挙動をするかわからない、という可能性もあるわけで。
というわけで、このfgetcsv()関数を使う際、enclosuredelimiterは省略可能なオプションとして設定されていますが、必ず指定した方が良さそうです。
また、色々ぐぐってみたところ「fgetcsv()関数はあてにならない」というような意見も結構見受けられましたので、使いどころには気をつけた方が良さそうです。

Twitterつぶやく
阿部辰也へのお仕事のご依頼・お問合せはこちら

Twitter始めました。Followはお気軽にどうぞ。

関連するブログ記事
カテゴリー
PHP
タグ
fgetcsv | PHP
現在位置
TOP > Web制作技術 > PHP > fgetcsv()関数について
前のブログ記事
「Wonderland」 - 稲葉浩志 [2007年12月 4日 10:49]
次のブログ記事
「ARIGATO」 - B'z [2007年12月 6日 23:59]

トラックバック(0)

このブログ記事に対するトラックバックURL:

コメント(2)

fnuzis [2015年5月13日 06:44]

zqeweyg

ambien [2015年6月18日 19:22]

コメントする


画像の中に見える文字を入力してください。