SplFileObjectとPHP5.4のCallbackFilterIteratorでCSV処理
普段はSPLをほとんど使っていない(DBからのファイル出力でIteratorを使ったことがあるくらい)のですが、練習のためにSplFileObjectを使ったCSV処理を書いてみました。
ただそれだけだと面白くないので、SplFileObjectを拡張してcurrent()メソッドにコールバック処理を入れ、配列からオブジェクトに詰め替えつつ、PHP5.4から追加されたCallbackFilterIteratorを使ったバリデーションも試してみました。
サンプルではただforeach()で回してHTMLに出力しているだけですが、実際にはバリデーションで例外をスローして処理を中断したり、current()で取得したオブジェクトをDBに保存するような使い方を想定しています。
PHP5.3からはstr_getcsv()という1行分のCSV文字列を配列に変換する関数が追加され、配列へのコールバック処理やバリデーションもやりやすくなりました。
CSV処理に限らず、関数で楽に処理できるとついクラス設計の手間を惜しんでしまいますが、Iteratorとして実装しておくことで組み込みクラスの恩恵を受けられることを実感した次第です。
ちなみに「Iterator」でPHPマニュアルを検索してもファイルを扱えるイテレータを見つけられず、自分で書く羽目になるのでは…と思ったのですが、こちらの記事でSplFileObjectという隠れイテレータ(?)の存在を知りました。
見直されるべきPHP5の組み込みイテレータ - hnwの日記
http://d.hatena.ne.jp/hnw/20090523
[追記]
CallbackFilterIteratorでたとえばforeach($items as $index => $item)と書いた場合、$itemで取得できるのはフィルタがtrueを返した要素だけですが、$indexも同様にその要素のインデックスが返されます。
(HTMLのテーブル出力で行毎に出力を変えているところで別の変数を定義しているのはそのためです)