Tech Racho エンジニアの「?」を「!」に。
  • 開発

CakePHPのfind, findAll, findCount, delete, deleteAll

追記: 馬場が記事にしてくれたCakePHP findの形式も非常に参考になります!

開発ブログには初投稿です。
よろしくお願いします。

今回は最近話題のCakePHPでモデル(データベーステーブル)からデータを取り出したり、カウントしたりするためのfind, およびfindCountの使い方をまとめてみたいと思います。
そんなの本でもWebにでもどこでも載ってるよ!と言われるかもしれませんが、実際に使ってみて1.1に沿ったの内容の解説が多かったり、内容が不正確であったりと困惑したためCakePHP1.2で実際に動くコードということで改めてまとめてみたいと思います。
また、データを削除する際に便利なdeleteやdeleteAllについても触れてみます。
本稿で想定しているCakePHPのバージョンは1.2です。
最近1.2の安定版も出ましたので、これからCakePHPの開発というと1.2が主流になってくるのではないかと思います。

findおよびfindAll
データベースからデータを取得するにはモデルオブジェクトのfindメソッドやfindAllメソッドを使うのがCakePHPの一般的なやり方です。
findAllは以下のようにして使います。タイプ数が少なくて便利なのですが、今後find("all", ...)形式の呼び出しに統一されやがてfindAllという名前のメソッドはなくなる予定だそうです。

findAllの使い方:

// 取得するフィールドや取り出す並び順が決まっている場合
function someaction() {
    $condition = array("hoge" => 1);
    $fields = array("id", "hoge", "hogege", "moge", "mogege");
    $order = "moge";
    $records = $this->Model->findAll($condition, $fields, $order);
}

// 並び順デフォルト、取得するフィールド全ての場合
function someaction2() {
    $condition = array("hoge" => 1);
    $records = $this->Model->findAll($condition);
}

findで条件に合致する最初の1件のレコードを取得する:

// 取得するフィールドや取り出す並び順が決まっている場合
function someaction() {
    $condition = array("hoge" => 1);
    $fields = array("id", "hoge", "hogege", "moge", "mogege");
    $order = "moge";
    $record = $this->Model->find(
        "first",
        array("conditions" => $condition, "fields" => $fields, "order" => $order)
    );
}

// 並び順デフォルト、取得するフィールド全ての場合
function someaction2() {
    $condition = array("hoge" => 1);
    $record = $this->Model->find("first", array("conditions" => $condition));

    // $record= $this->Model->findByHoge(1);
    // という書き方もできます
}

findで条件に合致する全てのレコードを取得する:

// 取得するフィールドや取り出す並び順が決まっている場合
function someaction() {
    $condition = array("hoge" => 1);
    $fields = array("id", "hoge", "hogege", "moge", "mogege");
    $order = "moge";
    $records = $this->Model->find(
        "all",
        array("conditions" => $condition, "field" => $fields, "order" => $order)
    );
}

// 並び順デフォルト、取得するフィールド全ての場合
function someaction2() {
    $condition = array("hoge" => 1);
    $records = $this->Model->find("all", array("conditions" => $condition));
}

findByIdでフィールド'idが特定の値の1件のレコードを取得する:

function someaction() {
    $record = $this->Model->findById(1); // idが1のレコードを取り出す
}

帰ってくるデータ:

// findAllやfind("all", ...)で帰ってくる形式(複数レコード)
array(
    [0] => array(
        "ModelName" => array(
            "field1" => "value1",
            "field2" => "value2"
        )
    ),
    [1] => array(
        "ModelName" => array(
            "field1" => "value1",
            "field2" => "value2"
        )
    ),
    ...
)

// findByXxxやfind("first", ...)で帰ってくる形式(単一レコード
array(
    "ModelName" => array(
        "field1" => "value1",
        "field2" => "value2"
    )
)

findCountで条件にマッチする行数を数える:

function someaction() {
    $condition = array("year" => 2009);
    $count = $this->Model->findCount($condition);
    // array("conditions" => $conditition)のような形式のオプション配列ではない,
    // findAllに与えるようなarray("field" => "value")形式の配列でよい
}

findAllやfind("all", ...)で取り出してcount()してもいいのですが、マッチする件数が多い場合はメモリを食いつぶしてしまいますので、
RDBMSに数えてもらうようにするのがスマートな実装でしょう。

deleteメソッドやdeleteAllメソッドでレコードを削除する

// deleteメソッド: 単一のレコードをIDで指定して削除
function someaction() {
    $deleteTargetID = 1;
    if ($this->Model->delete($deleteTargetID)) {
        // 成功
    } else {
        // 失敗
    }
}

// deleteAllメソッド: 条件にマッチする複数のレコードを一括して削除する
function someaction2() {
    $deleteCondition = array("year" => 2009);
    if ($this->Model->deleteAll($deleteCondition)) {
        // 成功
    } else {
        // 失敗
    }
}

deleteメソッドもdeleteAllメソッドも成功すると真を返します。
ちなみにdeleteAllにarray("conditions" => $condition)のようなfindのオプション形式の配列を渡すと必ず真が帰ってくるので気を付けましょう!

CakePHPはまだ日本語のドキュメントも不十分でWeb上にも1.1と1.2の情報が完全に整理されないまま混在しているため、
開発も手探り感が強いですが基礎の部分をしっかり理解して使いこなせば役に立つツールのひとつだと思います。
今後もCakePHPに関する情報を掲載していきたいと思いますのでよろしくお願いします。
コメントやトラックバックでのツッコミも歓迎致します!

参考:


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。