のえら

技術備忘とかメモとか.間違いはつっこんでいただきたい所存.アフィリエイトはやっていません.

CakePHP学習記録 そのさん find 関数の type について学ぶ

# 副題つければよかったんや。。

公式サイトのBlogチュートリアルでシンプルなアプリケーションの動きを確認したので、続けてデータの取得について学ぶ。
※戻り値の確認には debug() を使用

find 関数の定義

find(string $type = 'first', array $params = array())

type は戻り値の形式が変わる。'all', 'first', 'count', 'list', 'neighbors', 'threaded'と、自分で定義したタイプを指定できる。
params は検索条件などを指定することができる。キーの指定は任意。
(長くなったので、params についてはまた別途調べる)

type 別取得結果の違い

それぞれの type で戻り値がどう変わっているか確認する。ざっくり確認するために、params は指定しない。また、アソシエーションについても触れない。

find('all')

配列で結果を返す。

$this->Post->find('first');

出力された SQL

SELECT `Post`.`id`, `Post`.`title`, `Post`.`body`, `Post`.`created`, `Post`.`modified` FROM `cake`.`posts` AS `Post` WHERE 1 = 1

戻り値

array(
	(int) 0 => array(
		'Post' => array(
			'id' => '1',
			'title' => '888',
			'body' => 'あああ',
			'created' => '2014-04-28 10:58:58',
			'modified' => '2014-05-01 13:46:07'
		)
	),
	・・・中略・・・
	(int) 7 => array(
		'Post' => array(
			'id' => '13',
			'title' => 'title2',
			'body' => 'body2',
			'created' => '2014-04-28 15:11:44',
			'modified' => '2014-04-28 15:11:44'
		)
	)
)
find('first')

結果を1行だけ返す。

$this->Post->find('first');

出力された SQL

SELECT `Post`.`id`, `Post`.`title`, `Post`.`body`, `Post`.`created`, `Post`.`modified` FROM `cake`.`posts` AS `Post` WHERE 1 = 1 LIMIT 1

戻り値

array(
	'Post' => array(
		'id' => '1',
		'title' => '888',
		'body' => 'あああ',
		'created' => '2014-04-28 10:58:58',
		'modified' => '2014-05-01 13:46:07'
	)
)

limit で取得上限を1件にしている。違いを確認するために、type を 'all' にし、上限を1件だけにして実行してみる。

$this->Post->find('all', array('limit' => 1));

出力された SQL

SELECT `Post`.`id`, `Post`.`title`, `Post`.`body`, `Post`.`created`, `Post`.`modified` FROM `cake`.`posts` AS `Post` WHERE 1 = 1 LIMIT 1

戻り値

array(
	(int) 0 => array(
		'Post' => array(
			'id' => '1',
			'title' => '888',
			'body' => 'あああ',
			'created' => '2014-04-28 10:58:58',
			'modified' => '2014-05-01 13:46:07'
		)
	)
)
find('count')

件数を返す。

$this->Post->find('count');

出力された SQL

SELECT COUNT(*) AS `count` FROM `cake`.`posts` AS `Post` WHERE 1 = 1

戻り値

(int) 8
find('list')

インデックス付きの配列を返す。フォームのセレクトボックスやラジオボタンを生成するのに便利。
キーと値の組み合わせは params で fields を指定する、Model の displayField を使用する、などいくつかの方法で指定できる。

APIのfindに指定方法の説明がある。
訳(適当)とサンプルを以下に記述する。

If no fields are specified, then 'id' is used for key and 'model->displayField' is used for value.

fields が指定されていない場合は、キーに id を、値にモデルの displayField を使用する。
※ displayField はデフォルトで name か title を使用する。モデルの属性参照。

$this->Post->find('list');

戻り値

array(
	(int) 1 => '888',
	(int) 2 => 'またタイトル',
	(int) 3 => 'タイトルの逆襲',
	(int) 4 => '海を見にいきました',
	(int) 5 => '川を見にいきました',
	(int) 6 => '山を見に行きました',
	(int) 12 => 'title',
	(int) 13 => 'title2'
)
If a single field is specified, 'id' is used for key and specified field is used for value.

fields が一つ指定されている場合、キーに id を、値に指定されたフィールドを使用する。

$data = $this->Post->find('list', array(
	'fields' => array('Post.title')
));

戻り値

array(
	(int) 1 => '888',
	(int) 2 => 'またタイトル',
	・・・中略・・・
	(int) 12 => 'title',
	(int) 13 => 'title2'
)
If three fields are specified, they are used (in order) for key, value and group.

3つ fields を指定した場合、キーと値、グループに使用する。
※グルーピングについては今の構成だとサンプルになりそうなフィールドがないので省略・・・

Otherwise, first and second fields are used for key and value.

それ以外は、第1および第2フィールドをキーと値に使用する。

$this->Post->find('list', array(
	'fields' => array('Post.title', 'Post.created')
));

戻り値

array(
	(int) 888 => '2014-04-28 10:58:58',
	'またタイトル' => '2014-04-28 10:58:58',
	・・・中略・・・
	'title' => '2014-04-28 15:02:17',
	'title2' => '2014-04-28 15:11:44'
)
find('neighbors')

指定した条件の前後のデータを取得する。ページング処理などに使える。日記の「前の日」「次の日」とか。
前後の行「も」ってあるんだけど、前後「だけ」なのか・・・?

// id が2のデータの前後の行を取得する
$this->Post->find('neighbors', array(
	'field' => 'id', 'value' => 2
));

戻り値

array(
	'prev' => array(
		'Post' => array(
			'id' => '1',
			'title' => '888',
			'body' => 'あああ',
			'created' => '2014-04-28 10:58:58',
			'modified' => '2014-05-01 13:46:07'
		)
	),
	'next' => array(
		'Post' => array(
			'id' => '3',
			'title' => 'タイトルの逆襲',
			'body' => 'こりゃ本当にわくわくする!うそ。',
			'created' => '2014-04-28 10:58:59',
			'modified' => null
		)
	)
)
find('threaded')

入れ子になった配列を返却する。子要素も返るので、ツリー表示などに使える。