CakePHP/モデル/find

CakePHP/モデル/find

バージョンと製造年月日

  • 2011-09-06
  • CakePHP 1.3.8

基本!指定したズバリの条件で1件だけ引く

条件指定の1件引きはfind-first。これが基本。

$result = $this->find('first', array('conditions' => array('Hoge.id' => 123,
                                                           'Hoge.deleted' => null)));

リターンは連想配列でテーブル名のキーの下にさらに連想配列で

$result = array(
    "Hoge" => array(
        "id" => 123,
        "name" => "ほげ",
        "age"  => 32,
        "deleted" => null
    );
);

みたいな形になる。

合致するレコードが無いならばfalseが戻る(nullではない)

指定したズバリの条件で複数引く

条件指定の複数引きはfind-first。これが基本。

$result = $this->find('all', array('conditions' => array('Hoge.deleted' => null)));

返却の値はfind-allのパターン

順番を指定したい

順番を指定したい場合は orderというオプションを渡してやる

$result = $this->find("all", array("conditions" => array("Hoge.deleted" => null),
                                   "order"      => array("Hoge.created DESC", "Hoge.id ASC")));

SQL同様優先度順に書く

結合してもってきたい

通常は結合はアソシエーションで処理すればいいのだが、キーの制約やいろいろでできない場合がある。 PK絡みの結合しかできないからそれ以外のときはどうすればいい?joinsを使ってやろう。

$result = $this->find("first", array("fields"     => array("Hoge.*","Piyo.*","Fuga.*"),
                                     "conditions" => array("Hoge.id" => 123,
                                                           "Hoge.deleted" => null),
                                     "joins"      => array(
                                         array("type"       => "LEFT",
                                               "table"      => "piyos",
                                               "alias"      => "Piyo",
                                               "conditions" => "Hoge.name = Piyo.name"),
                                         array("type"       => "LEFT",
                                               "table"      => "fugas",
                                               "alias"      => "Fuga",
                                               "conditions" => "Hoge.age = Fuga.age")
                                     )));

↑のようになる。

まず基本となるモデルのfindから始める。 そしてfields指定。通常はいらないのだが、joinsを使った場合fieldsを省略するとfindを使っている基本のモデルのフィールドしか結果に出てこない。 なのでfieldsを明示的に指定してやる必要がある。

そしておなじみコンディション。

次にjoinsここで他のテーブルとの結合条件を指定してやるSQLなら「LEFT JOIN ON」にあたる部分を書く。joinsに結合条件をを「連想配列の配列」でわたしてやる。なぜかここ普通に単体の連想配列でパラメータを渡してもぶっ壊れたSQLは生成されるが、別にPHP的には普通に動いてしまうので注意。

typeで結合方式を指定する。大体の場合は「LEFT」だろう、次に結合先のテーブル名。次がaliasでSQLならテーブルに「AS」で付ける別名にあたる。ここを対応するモデル名にしておくと後々嬉しい。

そして最後に「ON」にあたるconditionsを書いて終了。

配列でこの条件をズラズラ書けば何個でもテーブルを結合できる。

結果はというとallやfirstに準拠する。aliasを指定したので

$result = array(
    "Hoge" => array(
        "id" => 123,
        "name" => "ほげ",
        "age" => 32
    ),
    "Piyo" => array(
        "name" => "ほげ",
        "memo" => "ゲゲゲ"
    ),
    "Fuga" => array(
        "age" => 32,
        "birth" => "2011-11-11 11:11:11"
    )
);

のようにアソシエーションでとってきたみたいになって非常に嬉しい。

ページングみたいな処理したい

findのoptionでconditionsと同階層に、「limit」と「page」というオプションが取れる。両方取れる値は数値でlimitが1ページあたりの最大件数、pageがページ数を表す。一番最初のページが1となっている。

どっちのパラメータもnullも取ることができて、null指定なら全件ということになる。

findされた値

find-firstした結果の値

find-firstした結果の値は↓のようにモデル名をキーにした連想配列でリターンされる

array(
    'Hoge' => array(
        'id' => 1,
        'piyo_name' => 'うんこ',
        'created' => '2011-08-11 12:13:54',
    )
);

find-firstの結果件数がゼロの場合はnullではなく厳密にfalseが返るようになっている。PHP文脈では同じように扱われることが多いのであまりきにならないかもしれないが使い方を考えると知っておいたほうがいい。

find-allした結果の値

find-allした結果の値は↓のようにモデル名をキーにした連想配列の配列でリターンされる

array(
    array(
        'Hoge' => array(
            'id' => 1,
            'piyo_name' => 'うんこ',
            'created' => '2011-08-11 12:13:54'
        )
    )
    array(
        'Hoge' => array(
            'id' => 2,
            'piyo_name' => 'うんこさん',
            'created' => '2011-08-11 12:13:55'
        )
    )
 
);

結果がゼロの場合はfirstとは違い、空配列が戻るようになっている。

queryした結果の値

queryの場合はASしたテーブル名をキーにした連想配列の中にASしたカラム名をキーにした値が詰まった連想配列の配列で返ってくる。

count等のメソッドを使って出力のカラムを増やした場合はテーブル名ではなく'0'というキーの要素の連想配列に格納される。

findの形式死守!

findの形式は1個の連想配列にいモデル名のキーにフィールド名の連想配列がくっついている形式になっている。 この一番上位のモデル名は邪魔といえば邪魔なのだがモデルではこのfindの出力を死守しておいたほうがいよい。

逆に言うとこの形式をリターンしないメソッドはfindを名乗ってはダメだと思う。

リターンが連想配列なのでモデルはほっておくと自由になんでもリターンするようになってしまう。 それはそのうちviewが要求する形をリターンするに至る。

そうするとせっかく3層分離してるのに結局1直線につながってしまうのだ。モデルのview依存があがってしまってさいりようせいが落ちるのでfind形式は死守しよう。

findされた結果の中の値の型

findされた結果の値というのは連想配列とか連想配列の配列とかになって戻ってくる。railsのようにメソッドまで装備したオブジェクトとしては戻ってこない。

MySQL CakePHP
integer 数値っぽい文字列
datetime yyyy-mm-dd hh:mm:ssの時刻っぽい文字列

参考:PHP / Ope / 日時操作

タグ

php/cakephp/model/find.txt · 最終更新: 2019-12-24 17:14 by ore