こんにちは。 セカイエアドベントカレンダー4日目を担当します。大西です。
本日は、弊社システムで利用している CakePHP2.x の便利機能などを紹介したいと思います。
※基本的にマニュアルに載ってるのでマニュアルはちゃんと読みましょうね(^_-)-☆
コンテンツ — CakePHP Cookbook 2.x ドキュメント
Containableビヘイビア
Containable — CakePHP Cookbook 2.x ドキュメント
これ CakePHPer なら使ってて当たり前の機能なのですが、とっても便利!
皆さんモデルでアソシエーションを設定しますよね?
でも過度にアソシエーションを設定すると find でデータを取得する時、アソシエーションで設定したモデルのデータをすべて取得してしまいます。
データ持ってきすぎ!!
こうなるとパフォーマンスにも影響を及ぼしてしまいます。
この問題を解決するために Containable ビヘイビアが便利です。
普通に find すると User モデルにアソシエーションの設定をしている Post モデルと Image モデルを取得するとします。
<?php $this->User->find('first'); array( [User] => array( [id] => 1, [name] => 'hoge', [sex] => 'male' ), [Post] => array( [0] => array( [id] => 1, [user_id] => 1, [title] => 'title1' [body] => 'body1' ), [1] => array( [id] => 1, [user_id] => 1, [title] => 'title1' [body] => 'body1' ) ), [Image] => array( [0] => array( [id] => 1, [user_id] => 1, [image] => 'user_1_1.jpg' ), [1] => array( ・・・ ) ) );
でも、今必要なのは Post モデルだけなんです。Image モデルは要らないんです。そんなとき!!登場するのが Containable ビヘイビア。
こんな使い方をします。
<?php $this->User->find('first', array( 'contain' => array('Post') )); array( [User] => array( [id] => 1, [name] => 'hoge', [sex] => 'man' ), [Post] => array( [0] => array( [id] => 1, [user_id] => 1, [title] => 'title1' [body] => 'body1' ), [1] => array( [id] => 1, [user_id] => 1, [title] => 'title1' [body] => 'body1' ) ) );
はい、要らない Image モデルの情報を取得しないようになりました。
Containable を使うと更に、「取得するフィールドを指定」したり、「取得する条件(conditions)を指定」することも出来ます。
ぜひ使ってみてください!!
Hash ユーティリティ
Hash — CakePHP Cookbook 2.x ドキュメント
配列をエエ感じ操作できるユーティリティです。
その中でも私がよく使うのが combine です。
<?php Hash::combine(array $data, $keyPath = null, $valuePath = null, $groupPath = null) # $keyPath : 配列のキーとなる値のパスを記述します。 # $valuePath : 配列の value になる値のパスを記述します。 # $groupPath : $keyPath, $valuePath をグルーピングする値のパスを記述します。
少しややこしい説明ですが、これを使うと簡単に配列のフィルタリングやグルーピングが出来ちゃいます。
<?php $a = array( [0] => array( [Goods] => array( [id] => 1, [name] => 'goods_1', [maker_id] => '1' [Maker] => array( [id] => 1, [name] => 'maker_1' ) ), [1] => array( [Goods] => array( [id] => 2, [name] => 'goods_2', [maker_id] => '1', [Maker] => array( [id] => 1, [name] => 'maker_1' ) ), [2] => array( [Goods] => array( [id] => 3, [name] => 'goods_3', [maker_id] => '2', [Maker] => array( [id] => 2, [name] => 'maker_2' ) ), ) ); $b = Hash::combine($a, '{n}.Goods.id', '{n}.Goods.name'); $b = array( [1] => 'goods_1', [2] => 'goods_2', [3] => 'goods_3' ); $c = Hash::combine($a, '{n}.Goods.id', '{n}.Goods.name', '{n}.Goods.maker_id'); # メーカー ID でグルーピング # キーは Goods.id で値は Goods.name $c = array( [1] => array( [1] => 'goods_1', [2] => 'goods_2' ), [2] => array( [3] => 'goods_3' ) );
他にも extract や map 等、便利なメソッドもあるので是非使ってみてください!!
CakePHPを拡張!?
色々な案件をやっていると、どうしても CakePHP デフォルトの動きでは実現できないものが出て来ると思います。
そんな時はいっそ CakePHP をヤメちゃいましょう!!
・
・
・
みたいなことは簡単には出来ないので、CakePHP を機能を拡張して対応します。
弊社ではデフォルトの Pagination ヘルパーでどうしても対応できない箇所があったので、PaginatorHelper を拡張して利用してます。
そこのあなた。。CakePHP を拡張するとき、本体をそのまま変更してませんか??
ダメです!!
もちろんそうすることでも出来るのですが、もし他のシステムが同じCakePHPの上で動いた時に弊害が発生する可能性があるので、
なるべく影響範囲を少なくして対応するようにしましょう。
では実際にどうやって拡張するのか紹介します。
今回は PaginatorHelper を拡張するので app ディレクトリの View/Helper ディレクトリ内に PaginatorExHelper.php というファイルを作ります。
中身は以下のように、PaginatorHelper を継承したクラスを作ります。
そして、拡張したいメソッドを好きなように拡張してもらったら良いです。
<?php App::uses( 'PaginatorHelper', 'View/Helper' ); class PaginatorExHelper extends PaginatorHelper { ・ ・ ・ }
そして PaginatorHelper を利用するコントローラーで以下の用にヘルパーの定義をします。
<?php class HogeController extends AppController { public $helpers = array('Paginator' => array('className' => 'PaginatorEx')); ・ ・ ・ }
こうすることで、拡張した PaginatorExHelper を利用することが出来ます。
これは他のコアユーティリティやビヘイビア、コンポーネントなども同じように拡張することが出来ます。
ぜひ色々試してみてください!!!
以上で CakePHP の便利機能や CakePHP の拡張方法を紹介しました。
これであなたも脱CakePHP初心者!!
最後に
CakePHP に限らずですが、マニュアルをしっかり読むことが大事です。
マニュアル読んでもわからないことは先人たちの知見を Google 先生で調べるかソースコード追えばだいたいの事はわかると思います。
これからもそうやって様々な技術を習得していきたいですね。というかしていきます!
今日はセカイエアドベントカレンダー4日目でした。
明日の担当は増井さんです。
ほな!