そろそろCSVHubについて一言いっておくか。もしくは、README.mdサボってごめんなさい!Yacsv pluginの使い方
CakePHP の噂のYACSVプラグイン。使いたいのだが、ドキュメントはいずこ?
https://t.co/jOGOtBds7m
— ITかあさん (@chihiro_kaasan) July 18, 2013
えーと、1年以上前にYacsvというCSVのインポート処理を簡単にするためのCakePHP pluginを作りました。
さらに、PHP Matsuri 2012でYacsvをコアにおいたCSVHubというWebサービスを作りました。
が、README.mdを書くのをサボってました。ゴメンナサイ。。。
Yacsvって何?
数あるCSVインポート系のPluginの一つです。「Yet another CSV」の略です。
ちなみに自分はこの「Yet another」という言葉が大好きで、Yacsv以外にも
- yak [Yet Another Ktai plugin]
- Yasd [Yer Another SoftDeletable Behavior]
- Yav [Yet Another Validation Set]
- Yamd [Yet Another Markdown plugin]
など、命名に困ったらかたっぱしから「Ya」をつけます。紛らわしいことこの上ない。
Yacsvの特徴は、特にこれといったものはないのですが、強いて言うなら
- CSVのパーサが強力(自分が作ったものではない)
- 使用するとき記述量が少ない
- テストがある
- README.mdにドキュメントが書かれていない
といったところでしょうか。
CSVのパーサが強力
これはYacsvの公開の条件でもあったのですが、YacsvのCSVのパーサは@yossy222さんの作成されたfgetcsv_reg()を元に作成されています。
関数利用許可を得られたのでYacsvをリリース https://t.co/ykG5aDKI 内部で@yossy222さんのfgetcsv_reg()を一部改変して利用しています。
— k1LoW (@k1LoW) March 5, 2012
どれだけ強力かについては定量的なデータはないのですが、 基本的に今まで、Yacsvを使ってパース周りで問題が起きたことはありません。
ちゃんとパースできるかについて試したいのであれば、是非CSVHubにアップロードしてみてください。設定すればちゃんとパースされますよ。
使用するとき記述量が少ない
Yacsvは基本的にBehaviorとして動くのですが、CakePHPに特化しているので記述量が少ないです。
いや、汎用的に作っていますので、常に少ないわけではありません。多分多くなるときもあります。
例えば
既にModel::save()に近いインターフェースでデータ登録メソッドをモデルに作ってシステムを作っていたら、いきなり『CSVインポート機能も作って』と言われた
こういうときに圧倒的に記述量が少ないです。
え?ニッチ過ぎるって?
では言い換えます。
まずModel::save()に近いインターフェースでデータ登録メソッドを作り、それからCSVインポート機能を作るとわかりやすいし、記述量も少ない
どうでしょう?
作り方は大体わかるけど毎回面倒なCSVアップロード機能が簡単につくれそうじゃないですか?
テストがある
suzukiさんに協力してもらい、しっかりテストがあります(機能追加もありました)。また、はやりのTravis CIでCIされています。
README.mdにドキュメントが書かれていない
大変申し訳ありません。
Yacsvの使い方
いろんな使い方ができるのですが、今回は本当にスタンダードな使い方をサンプルアプリケーションの「コミットログ」を見ながら確認していきましょう。
1. CakePHPの初期セットアップ
まずは何は無くともCakePHP
commit/6980e8fe0e6deeb2924c94980bcaca39231d96d7
CakePHPを設置しSqlite3のデータベースにpostsテーブルだけつくりました。あとはbakeをしたくらい。
2. Postモデルにバリデーションを記述
commit/11088e37fb65959ea05d8bd6b1ebec79a7f07e27
まずはバリデーションを記述します。
ここでposts/add
で登録しようとしたら、Post::save()のタイミングでちゃんとバリデーションチェックが走ります。よね?
3. CSVインポート機能を作成開始
ここで、postsテーブルへのCSVインポート機能を実装してみましょう。
まずはYacsvをapp/Pluginに設置
commit/a3eeefcdaf85e1d16b886c8f7a81b7dbd1d1d7fa
Yacsvをbootstrap.phpでloadしてPost::actsAsに記述します
commit/be2757669726eb0ae937be2cf7054ed838275602
当然インポート画面が必要ですので、posts/importページの雛形を作成しましょう。CSVファイルアップロードに使うフィールド名は、とりあえずcsvfileにします。
Viewはファイルアップロードである点に注意してadd.ctpを元に作成。Controllerのアクションはまずはposts/addをコピペしました
commit/8d682a9e0c2dd94a6cdbb417b92ed8f4e84c6044
4. Yacsvの設定 (Post::save()を利用してCSVインポート機能を実装する)
さて、ここからがYacsv独特の設定です。Yacsvの設定はCakeDC製のSearch pluginの設定方法に近い形で実装しています。ちょっと近いだけですが。
今回インポートするCSVはこんな感じです。
commit/34f304ced212b7c577c1850f40ed4f50ae827666
ExcelからCSV出力されたものなので、Shift-JISになっていますが、実際にはこんな感じです
タイトル,内容
PHPMatsuri2012でCSVHubをつくりました,"PHPMatsuri2012でCSVHubをつくりました。
とても楽しかったです。"
PHPMatsuri2013でdevil's pieをつくりました,"PHPMatsuri2013でdevil's pieをつくりました。
とても楽しかったです。"
ヘッダがあったり、改行があったりするやつですね。
まず、Postモデルの設定をしましょう。詳しくはPost.phpに追記したコメントをみてください。
commit/f344eb2f769122d126f678a6cd042fb493b22d25
次に、PostsController::importアクションの設定をしましょう。いろいろな設定が結構auto
で設定できる場合があるのがYacsvのいいところですね。
commit/16313f2475a2191227ec192df8835ba575de4a7b
YacsvはExceptionを吐くので、少々強引ですがtry/catchで囲みます。
(また、YacsvのExceptionはあまり親切ではないことが知られていますので、ここは頑張ってください。。。。)
で、終了です。簡単な実装はこれだけです。
5. Yacsvのアドバンスドな使い方その1 各行のバリデーションエラーを表示する
4までのCSVインポート、ちゃんとPost::validateを使っています。では各行のバリデーションエラーを表示してみましょう(デザインは適当です)。
commit/f85ee0c13ca33c5d59d6e0cb5f19ef69e3b74636
6. Yacsvのアドバンスドな使い方その2 独自の登録メソッドを使ってCSVインポート機能を実装する
4までのCSVインポートでは、Post::save()を使っていましたが、ちょっと特殊な登録方法だったりすることありますよね?
commit/12d65a585c87a2218607428010b6bafbe65ba915
(今回のサンプルはbeforeSaveでもできますが、まあそこは目をつぶってください^^)
こういうときはPost::importCSV()のオプションをこんな感じで修正するだけでOKです。
commit/a4b06ed95ae6a3ee768622915e553597a72aa9e4
細かすぎて伝わりにくいかもしれませんが、このsaveMethod
、実際にかなり使えます。実際の案件でModel::save()で済むようなことはほとんどないですからね。
というわけで
いかがだったでしょうか?
ちなみに今回のサンプルアプリケーションは、app/tmpのパーミッションをいつものように修正するだけで動きますので、設置して触ってみてもらえればと思います。
k1LoW/Sample-Yacsv-Application
このエントリーもってREADME.mdの代わりにしていただければ。。。