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番目のパラメータで 指定しない限り、デフォルトではダブルクォーテーショーンマークとなります。 enclosure と delimiter はそれぞれ1文字に限られており、もし1文字を超える文字列が指定された場合は、 最初の文字だけが使われます。
日本PHPユーザ会のマニュアル内「fgetcsv」の頁より。
つまり、ファイルを一行ずつ読み込んで、特定の区切り文字でsplitして、という作業をこの関数が一発で済ましてくれるわけです。
ここでまず重要なのは最後の「enclosure と delimiter はそれぞれ1文字に限られており、もし1文字を超える文字列が指定された場合は、 最初の文字だけが使われます。」という一文。
フィールドの区切りは1文字に限定されますので、perlのcgiなんかでよく使われていた(orる)「<>」を区切りに使う手法は使えません。
カンマ「,」区切りとか、タブ「\t」区切りとかを使いましょう。
「もし1文字を超える文字列が指定された場合は、 最初の文字だけが使われます。」とありますが、「\t」を「\」と「t」の二文字として判断したりはしません。
次に、「enclosure (フィールド囲い子) パラメータは、別の文字を4番目のパラメータで 指定しない限り、デフォルトではダブルクォーテーショーンマークとなります。」という一文。
私はマニュアルを良く読まずに「enclosureを指定しなければ、フィールドの囲い子は「ない」として扱われると思いこんでいたため(そしてうちのサーバーではそれで問題なく動いてしまっていた)、そのスクリプトを他所様のサーバーで動かすと大量に文字化けが発生してしまいました。
この件の場合、fgetcsv()を使っている箇所は何も弄らずに、データ自体の各フィールドをダブルクォーテーションで括るようにしたところ、無事に意図通りの挙動をするようになりました。
とは言え、enclosureを指定せず、データの囲い子がない状態でもうちのサーバーだとちゃんと区切ってくれたと言うことは、逆にenclosureをちゃんと指定しておかないとどういう挙動をするかわからない、という可能性もあるわけで。
というわけで、このfgetcsv()関数を使う際、enclosure と delimiterは省略可能なオプションとして設定されていますが、必ず指定した方が良さそうです。
また、色々ぐぐってみたところ「fgetcsv()関数はあてにならない」というような意見も結構見受けられましたので、使いどころには気をつけた方が良さそうです。
- 現在位置
- TOP > Web制作技術 > PHP > fgetcsv()関数について
- 前のブログ記事
- 「Wonderland」 - 稲葉浩志 [2007年12月 4日 10:49]
- 次のブログ記事
- 「ARIGATO」 - B'z [2007年12月 6日 23:59]
コメント(2)
zqeweyg
mgucrq http://cheaponlinepharmacy24x7.com/ambien.php/ ambien
コメントする