よく使うコーディング方法などを備忘録的に書いていきます。
可読性向上?
find()の第二引数にcompact()を使う
例文などで以下のような書き方をよく見ますが
find()の第二引数に渡すパラメータは、ゴチャゴチャした多次元配列になりがちです。
$articles = $this->Article->find('all', array(
'conditions' => array(
'Article.status !=' => 'pending',
'Article.date >=' => '2016-02-01',
'Article.date <=' => '2016-02-28',
),
'fields' => array(
'Article.id',
'Article.title',
'Article.date',
),
'order' => array('Article.date' => 'desc'),
'limit' => 10,
));
好みの問題ですが、これだと少し可読性が悪い気がするので
(僕は関数の引数に配列をずらずら書くのが好きではないため)
以下のように各パラメータを一旦変数に代入してから、PHP標準関数のcompact()を使ってfind()に渡します。
$conditions = array(
'Article.status !=' => 'pending',
'Article.date >=' => '2016-02-01',
'Article.date <=' => '2016-02-28',
);
$fields = array(
'Article.id',
'Article.title',
'Article.date',
);
$order = array('Article.date' => 'asc');
$limit = 10;
$articles = $this->Article->find('all', compact('conditions', 'fields', 'order', 'limit'));
※変数名がそのまま配列のキーになるので、find()のパラメータで指定可能な変数名を付けます。
[compact関数]
http://php.net/manual/ja/function.compact.php
[findに指定可能なパラメータ]
http://book.cakephp.org/2.0/ja/models/retrieving-your-data.html
突っ込みどころはありそうですが、それぞれのパラメータが独立して見分けやすく、こちらの方がスッキリして好きです。
Hashクラスでarray地獄を脱出
CakePHP2.xのfind('all')では、モデル名を含む連想配列を返します。
例) 結果をprint_rで出力したもの
Array
(
[0] => Array
(
[Article] => Array
(
[id] => 385
[title] => 円急騰 企業業績や株価に逆風写真
[date] => 2016-02-11 22:23:00
)
)
[1] => Array
(
[Article] => Array
(
[id] => 526
[title] => 重力波を初観測 ノーベル賞級
[date] => 2016-02-12 01:07:00
)
)
[2] => Array
(
[Article] => Array
(
[id] => 692
[title] => 大谷を絶賛「5億ドルの価値」
[date] => 2016-02-12 05:49:00
)
)
)
この配列をforeachで回して自分が望む形式に加工したりしますが
CakePHP2.xにはHashという配列を扱うユーティリティクラスがあるので
これを使うと簡単に配列操作できたり、コードがスッキリして幸せになれます。
[Hashクラス]
http://book.cakephp.org/2.0/ja/core-utility-libraries/hash.html
Hash::extractで必要なデータだけ取り出す
// findでデータ取得 (上記例の配列が返る)
$articles = $this->Article->find('all', compact('conditions'));
// idだけのリストを作成したい場合
$id_list = Hash::extract($articles, '{n}.Article.id');
print_r($id_list);
/*
Array
(
[0] => 385
[1] => 526
[2] => 692
)
*/
// titleだけのリストを作成したい場合
$title_list = Hash::extract($articles, '{n}.Article.title');
print_r($title_list);
/*
Array
(
[0] => 円急騰 企業業績や株価に逆風写真
[1] => 重力波を初観測 ノーベル賞級
[2] => 大谷を絶賛「5億ドルの価値」
)
*/
// 1行にまとめるとスッキリ
$id_list = Hash::extract($this->Article->find('all', compact('conditions')), '{n}.Article.id');
Hash::combineで連想配列を作る
// findでデータ取得 (上記例の配列が返る)
$articles = $this->Article->find('all', compact('conditions'));
// idとtitleの連想配列を作成したい場合
$id_title = Hash::combine($articles, '{n}.Article.id', '{n}.Article.title');
print_r($id_title);
/*
Array
(
[385] => 円急騰 企業業績や株価に逆風写真
[526] => 重力波を初観測 ノーベル賞級
[692] => 大谷を絶賛「5億ドルの価値」
)
*/
// 1行にまとめるとスッキリ
$id_title = Hash::combine($this->Article->find('all', compact('conditions')), '{n}.Article.id', '{n}.Article.title');
結果からモデル名を除去する
// findでデータ取得 (上記例の配列が返る)
$articles = $this->Article->find('all', compact('conditions'));
// モデル名を除去したい場合
$ext = Hash::extract($articles, '{n}.Article');
print_r($ext);
/*
Array
(
[0] => Array
(
[id] => 385
[title] => 円急騰 企業業績や株価に逆風写真
[date] => 2016-02-11 22:23:00
)
[1] => Array
(
[id] => 526
[title] => 重力波を初観測 ノーベル賞級
[date] => 2016-02-12 01:07:00
)
[2] => Array
(
[id] => 692
[title] => 大谷を絶賛「5億ドルの価値」
[date] => 2016-02-12 05:49:00
)
)
*/
AppModelのafterFind()に書いておいても良いかも。