元々はComma-Separated Valuesの名のとおりカンマで区切られたフィールドを扱うフォーマットです。カンマ以外のデリミタ(区切り文字)のもの(タブ区切りのTSVや半角スペース区切りのSSVなど)も含めてCharacter-Separated Values(CSV)とかDelimiter-Separated Valuesと呼ばれることもあります。

データ交換用のフォーマットととして長く使われていますので、現在ではRFC4180で仕様が成文化されています。

http://www.ietf.org/rfc/rfc4180.txt
http://www.kasai.fm/wiki/rfc4180jp

phpスクリプトでCSVデータを扱うときの最善手はfgetcsv/fputcsvを使うことです。fgetcsv/fputcsvであれば、文字列データ中に改行コードが含まれているようなケースでも問題なく扱えます。現在のphpスクリプトでは、これ以外の選択肢は考えられません。

SplFileObjectを使うときは同様にfgetcsvメソッドがあります。



ということで以下は蛇足です(汗

fgetcsvがなかった頃の力技だと、作成時にはimplode、取り出し時にはexplodeを使うのが基本でした。現在でも、たまに自前で implode/explodeを使って処理しようとしているケースがあります。習作としてデータの扱いに慣れるための頭の体操としては意味があるのですが、カンマ(区切り文字)の取り扱いや二重引用符の取り扱いすら考慮してないケースがほとんどです。そういうスクリプトはデータの内容次第で簡単に破綻してしまいます。

  • データとして「改行」が存在すると扱いにくいので、作成時にはnl2brしたあとで、"¥r"と"¥n"を(個別に)削除する。読み込んでhtmlとして表示するときは「そのまま」。改行コードに戻したいときはを改行コードに置換する。もちろんなどの存在を認めるようなケースだと(いわゆるBBコード的な)別の文字列に置換することになります。

  • カンマは文字列データに存在する可能が高いのでデリミタをタブ("¥t")とする。文字列データ内に存在するタブコードは適当な文字列で置換する(ほとんど出現しないハズの文字コードだがコピペなどで混入する可能性がまったくゼロではないので)。

  • 文字列中に二重引用符があったら二重引用でエスケープ( " → "" で置換)し、文字列(フィールド)全体を二重引用符で括る。取り出し時には先頭+末尾が二重引用符だったら取り除き、"" を " で置換する。


phpの標準関数であるmb_send_mail()を使う場合の注意点です。標準で実装されていることから初心者が最初に作るメールフォームではmb_send_mailが多用されるようです。

#本来はPHPMailerなどのライブラリを使う方がベター

大事なのは、mb_languagemb_internal_encodingをキッチリ(正しく)書くこと

mb_languageとmb_internal_encodingさえちゃんと指定していれば、あとはほとんどの部分を自動的にやってくれます。自前で余計なことをしないように要注意です。

mb_languageが"ja"の場合はISO-2022-JP、"uni"の場合はUTF-8のメールが作成されます。

普段はほとんど意識しない(意識しなくても問題がない)mb_internal_encodingですが、mb_send_mailを使うときだけはちゃんと指定します。mb_internal_encodingで指定された文字セットからメールの文字セット(前述のとおりmb_languageの値に従ってISO-2022-JPもしくはUTF-8)に変換されます。

変換対象は第一引数から第三引数まで。つまり件名や本文は何も考えなくていいわけです。逆に言えば第四引数で自分でメールヘッダに何か指定するときには日本語の扱いには注意しないといけません。Fromヘッダにメールアドレスだけでなく自分の名前を入れたいという場合にはmb_encode_mimeheaderする必要があります。

なおmb_encode_mimeheaderも第二引数を省略した場合にはmb_languageの値を参照しますし、mb_internal_encodingからの変換も自動的にやってくれます(これも自前で変換したりするとおかしなことになります)。

開発途中での調べ物の結果とかちょこっと書いたソースとかを置いとくのにBlog追加しました。要するに備忘録です。そもそもYahoo!知恵袋の知恵ノートに書いていたものを(知恵ノートが提供終了になったので)どっかに移したかったという・・・

#正直、今さら感満載なんですが(汗

多分メインはphpに関する話題になると思います。