find('neighbors', $params) は 'first' と同じ検索を実行しますが、リクエストの前後の行を返します。これは簡単な(コントローラーコード)例です:
2 $neighbors = $this->Article->find('neighbors', array('field' => 'id', 'value' => 3));
この例では、$params 配列にはフィールドと値の 2 つの要素が含まれています。検索内の他のすべての要素は引き続き使用できます (たとえば、モデルが包含可能である場合、$params で 'includes' を指定できます)。 find('neighbors') を呼び出した結果の形式は次のとおりです:
結果には常に 2 つのルート要素 (prev と next) のみが含まれることに注意してください。この関数は、モデルのデフォルトの再帰変数を尊重しません。再帰設定は、必要な各呼び出しにパラメータとして渡す必要があります。
find メソッドは柔軟で、カスタム検索を受け入れることができます。カスタム検索は、モデル変数で独自の型を定義し、モデル クラスで特定の関数を実装することによって行われます。
他のタイプはどうですか?たとえば、データベース内のすべての公開記事を検索するとします。各変更は、モデル内の Model::$findMethods 変数に型を追加することによって行われます。
これは、CakePHP に、find 関数の最初のパラメーターとして使用可能な値を受け入れるように指示します。 2 番目のステップは、_findAvailable 関数を実装することです。 これは規則です。myFancySearch という検索を実装する場合は、_findMyFancySearch というメソッドを実装する必要があります。
7 return $query;
8 }
9 $results を返します;
10 }
11 }
完全な例 (コントローラー コード) を次に示します:
1 クラス ArticlesController は AppController を拡張します {
2
3 // 公開されたすべての記事を検索し、作成された列によって並べ替えます
4 パブリック関数 Index() {
5 $articles = $this->Article->find('利用可能', array(
)
6 'order' => array('created' => 'desc')
7 ));
8 }
9
10 }
上記のコード内の特定の _find[Type] メソッドは 3 つのパラメーターを受け取ります。 1 つ目は、クエリの実行がその状態にあるときを意味し、前後の可能性があります。 これは、この関数がコールバック関数であり、完了前にクエリを編集したり、取得した結果を編集したりできるためです。
通常、最初に行うことは、検索関数のクエリステータスを確認することです。 before 状態は、クエリを編集し、新しい関係をバインドし、追加の動作を適用し、find に 2 番目の引数として渡された特殊キーを解釈したときの状態です。この状態では、$query パラメータが (変更されているかどうかにかかわらず) 返される必要があります。
後の状態は、結果を確認し、新しいデータを挿入し、計算して別の形式で返すか、最近返されたデータに対して任意の操作を行うことです。この状態では、$result 配列が (変更されているかどうかにかかわらず) 返される必要があります。
カスタム ルックアップを好きなだけ作成できます。これは、アプリケーション内のモデル間でコードを参加させる優れた方法でもあります。
次のタイプのカスタマイズを使用して検索をページ分割することもできます:
1 クラス ArticlesController は AppController を拡張します {
2
3 // 公開されたすべての記事はページ分割されます
4 パブリック関数 Index() {
5 $this->paginate = array('available');
6 $articles = $this->paginate();
7 $this->set(compact('articles'));
8 }
9
10 }
上記のようにコントローラーで $this->paginate 属性を設定すると、検索の種類が使用可能になり、検索結果を引き続き変更することもできます。
ページング数が間違っている場合は、ページング数を修正できる次のコードを AppModel に追加する必要がある場合があります。
1 クラス AppModel はモデルを拡張します {
2
3 /**
4 * カスタム検索のカウントクエリの「fields」キーが配列の場合は、それを削除します。
5 * Model::_findCount() 呼び出しを完全に中断するためです
6 *
7 * @param string $state 「前」または「後」のいずれか
8 * @param 配列 $query
9 * @param 配列 $results
10 * @return int 見つかったレコードの数、または false
11 * @access protected
12 * @see Model::find()
13*/
14 保護された関数 _findCount($state, $query, $results = array()) {
15 if ($state === 'before') {
16 if (isset($query['type']) && isset($this->findMethods[$query['type']])) {
17 $query = $this->{'_find' . ucfirst($query['type'])}('before', $query);
18 if (!empty($query['fields']) && is_array($query['fields'])) {
19
20 unset($query['fields']);
21 }
22 }
23 }
24 }
25 returnparent::_findCount($state, $query, $results);
26 }
27
28 }
29 ?>
バージョン2.2で変更されました。
カウント結果のエラーを修正するために _findCount をオーバーライドする必要はもうありません。 カスタム ルックアップの「前」の状態が $query['operation'] = 'count' で再度呼び出されるようになりました。返された $query は _findCount() で使用されます。 必要に応じて、「operation」キーをチェックすることで、別の $query を識別して返すことができます:
1 つの保護された関数 _findAvailable($state, $query, $results = array()) {
2 if ($state == 'before') {
3 $query['条件']['Article.published'] = true;
4 if (!empty($query['operation']) && $query['operation'] == 'count') {
5 return $query;
6 }
7 $query['joins'] = array(
8 //必要な結合の配列
9 );
10 return $query;
11 }
12 $results;
13 }
マジック検索タイプ
これらのマジック関数は、特定の列に基づいてテーブルを検索するためのショートカットです。これらの関数の末尾に列名 (キャメルケース形式) を追加し、最初の引数としてそれらの列のルールを指定するだけです。
findAllBy() 関数は find('all') と同様の形式で結果を返しますが、findBy は find('first') と同じ形式で結果を返します。
すべて検索
findAllBy(string $value, array $fields, array $order, int $limit, int $page, int $recursive)
findAllBy 例 対応する SQL スニペット
$this->Product->findAllByOrderStatus('3'); Product.order_status = 3
$this->Recipe->findAllByType('Cookie'); Recipe.type = 'Cookie'
$this->User->findAllByLastName('Anderson'); User.last_name = 'Anderson'
$this->Cake->findAllById(7); Cake.id = 7
$this->User->findAllByEmailOrUsername('jhon'); User.email = 'jhon' OR User.username ='jhon';
$this->User->findAllByUsernameAndPassword('jhon', '123'); User.username = 'jhon' ANDUser.password = '123';
$this->User->findAllByLastName('psychic', array(),array('User.user_name => 'asc')); User.last_name = 'psychic' ORDER BYUser.user_name ASC
返される結果の配列の形式は、find('all') の戻り値の形式と似ています。
探す
findBy<フィールド名>(string $value);
findBy マジック関数は、いくつかのオプションのパラメーターも受け入れます:
findBy(string $value[,mixed $fields[,mixed $order]]);
findBy の例 対応する SQL スニペット
$this->Product->findByOrderStatus('3'); Product.order_status = 3
$this->Recipe->findByType('Cookie'); Recipe.type = 'Cookie'
$this->User->findByLastName('Anderson'); User.last_name = 'Anderson';
$this->User->findByEmailOrUsername('jhon'); User.email = 'jhon' OR User.username = 'jhon';
$this->User->findByUsernameAndPassword('jhon','123'); User.username = 'jhon' AND User.password ='123';
$this->Cake->findById(7); Cake.id = 7
findBy() 関数は、find('first') と同様の結果を返します。
モデル::クエリ()
クエリ(文字列 $クエリ)
必要になることはほとんどありませんが、他のメソッドを通じて SQL を呼び出すことができない、または呼び出したくない場合は、モデルの query() メソッドを直接使用できます。
実際にアプリケーションでこのアプローチを使用したい場合は、CakePHP のデータ クレンジングを必ず読んでください。これは、ユーザーが指定したデータをクリーンアップして、インジェクションやクロスサイト スクリプティング攻撃を防ぐのに役立ちます。
メモ
query() は $Model->cacheQueries を無視します。これは、その機能が呼び出し元のモデルとは本質的に無関係であるためです。呼び出したクエリのキャッシュを回避するには、2 番目のパラメーターを false に設定します (例: query($query, $cachequeries = false))。
query() は、モデル名ではなく、クエリ内のテーブル名を返されるデータの配列キーとして使用します。例:
1 $this->Picture->query("SELECT * FROM photos LIMIT 2;");
次の配列を返す場合があります:
1 配列
2 (
3 [0] => 配列
4 (
5 [写真] => 配列
6 (
7 [id] => 1304
8 [user_id] => 759
9)
10)
11
12 [1] => 配列
13 (
14 [写真] => 配列
15 (
)
16 [ID] = >1305
17 [ユーザーID] => 759
18)
19)
20)
find メソッドの戻り結果と一貫性を保つためにモデル名を配列キーとして使用するには、クエリを次のように記述できます:
1 $this->Picture->query("SELECT * FROM photos AS Picture LIMIT 2;");
が返されます:
1 配列
2 (
3 [0] => 配列
4 (
5 [画像] => 配列
6 (
7 [id] => 1304
8 [user_id] => 759
9)
10)
11
12 [1] => 配列
13 (
14 [画像] => 配列
15 (
)
16 [ID] = >1305
17 [ユーザーID] => 759
18)
19)
20)
メモ
この構文と連想配列構造は MySQL でのみ有効です。 Cake はクエリを手動で実行するときに抽象データを提供しないため、結果はデータベースによって異なります。
モデル::フィールド()
フィールド(文字列 $name, 配列 $conditions = null, 文字列 $order = null)
戻り値は、$order で指定されたソート条件に一致する最初のレコードの $name で指定された 1 つの列のみです。条件が渡されず、モデルに ID が設定されている場合は、現在のモデル結果の列の値が返されます。一致するレコードがない場合、検索は false を返します。
1 $this->Post->id = 22;
2 echo $this->Post->field('name') // 行 ID 22 の名前をエコーします
3
4 echo $this->Post->field('name', array('created <' => date('Y-m-d H:i:s')), 'created DESC');
5 // 最後に作成されたインスタンスの「名前」列を表示します。
モデル::read()
読み取り($fields, $id)
read() は、現在のモデル データ (Model::$data) を設定するために使用されるメソッドです (編集中など) が、データベースから単一のレコードがフェッチされる他の状況では使用できません
$fields は単一の列の名前を渡すために使用されます。これは文字列または列名の配列にすることができ、空の場合はすべての列が取得されます。
$id は、読み取るレコードの ID を指定します。デフォルトは、Model::$id で指定された現在選択されているレコードです。 $id に別の値を渡すと、レコードが選択されます。
read() は常に配列を返します (列名が 1 つしか含まれていない場合でも)。 field を使用して、単一の列の値を取得します。
警告
read メソッドはモデルの data 属性と id 属性に保存されている情報を上書きするため、この関数を使用するとき、特に beforeValidata や beforeSave などのモデル コールバック関数で使用するときは十分に注意してください。一般に、find メソッドは、read メソッドよりも強力で使いやすい API を提供します。
複雑な検索条件
ほとんどのモデルの検索呼び出しでは、条件セットを渡す必要があります。通常、CakePHP は配列を使用して、SQL クエリの WHERE 句に配置する必要がある条件を結合します。
配列の操作はすっきりしていて読みやすく、クエリの構築は非常に簡単です。この構文は、クエリ内の要素 (列、値、演算など) も分割します。これにより、CakePHP がより効率的なクエリを生成できるようになり、SQL 構文が正しく、クエリの個々の部分が正しく分解されることが保証されます。配列構文を使用すると、CakePHP はクエリが SQL インジェクション攻撃から安全であることを保証することもできます。
配列に基づく最も基本的なクエリは次のようになります:
1 $conditions = array("Post.title" => "これは投稿です", "Post.author_id" => 1);
2 // モデルを使用した例
3 $this->Post->find('first', array('conditions' => $conditions));
この構造は非常に単純です。「これは投稿です」というタイトルの投稿が検索されます。列名として「タイトル」を使用することもできますが、コードの明瞭さが向上し、スキーマを変更する場合の競合を防ぐことができるため、クエリを構築するときは常にモデル名を指定することをお勧めします。
他のマッチタイプについてはどうですか?同様に簡単です。タイトルが「This is a post:
」ではないすべての投稿を検索したいとします。
1 array("Post.title !=" => "これは投稿です")
「!=」が列名の後に続くことに注意してください。 CakePHP は、列名と演算子をスペースで区切っている限り、LIKE、BETWEEN、REGEX を使用した一致式を含む、有効な SQL 比較演算子を解析できます。 IN(...) スタイルの一致例外。タイトルが指定された値セット内にある投稿を検索するとします。
1配列(
2 "Post.title" => array("最初の投稿", "2番目の投稿", "3番目の投稿")
3)
NOT IN(...) マッチングを実行して、タイトルが指定された値セット内にない投稿を検索するには:
1配列(
2 "NOT" => array("Post.title" => array("最初の投稿", "2 番目の投稿", "3 番目の投稿"))
3)
条件に追加のフィルタリングを追加することは、配列に追加のキーと値のペアを追加するのと同じくらい簡単です:
1 配列 (
2 "Post.title" => array("最初の投稿", "2 番目の投稿", "3 番目の投稿"),
3 "Post.created >" => date('Y-m-d', strtotime("-2 週間"))
4)
データベース内の 2 つの列を比較するルックアップを作成することもできます:
1 配列("Post.created = Post.modified")
上記の例は、作成時刻と編集時刻が同じ投稿 (つまり、一度も編集されていない投稿) を返します。
メソッド (論理演算など) で WHERE 句を生成できない場合は、文字列を使用していつでも WHERE 句を指定できることを覚えておいてください。
1配列(
2 'Model.field & 8 = 1',
3 // その他の一般的な条件
4)
デフォルトでは、CakePHP は論理 AND を使用して複数の条件を接続します。つまり、上記のスニペットは、2 週間前に作成され、指定されたセットの 1 つに一致するタイトルを持つ投稿にのみ一致します。ただし、いずれかの条件を満たす投稿を簡単に見つけることもできます:
1 array("OR" => array(
2 "Post.title" => array("最初の投稿", "2 番目の投稿", "3 番目の投稿"),
3 "Post.created >" => date('Y-m-d', strtotime("-2 週間"))
4))
CakePHP は、AND、OR、NOT、XOR などを含むすべての有効な SQL 論理演算を受け入れ、大文字と小文字は区別されません。これらの条件は制限なくネストできます。投稿と作成者の間に帰属する関係があり、特定のキーワード (「マジック」) を含む投稿、または 2 週間前に作成された (ただしボブのみが作成した) すべての投稿を検索したいとします。
1配列(
2 "著者名" => "ボブ",
3 "OR" => 配列(
4 "Post.title いいね" => "%magic%",
5 "Post.created >" => date('Y-m-d', strtotime("-2 週間"))
6)
7)
同じ列に複数の条件を設定する必要がある場合、たとえば複数の用語で LIKE 検索を実行する場合は、次のような条件を使用できます:
1 array('OR' => array(
2 array('Post.title LIKE' => '%one%'),
3 配列('Post.title LIKE' => '%two%')
4))
Cake は null 列をチェックできません。この場合、クエリは null 以外のタイトルを持つすべてのレコードを返します:
1 array("NOT" => array(
2 "Post.title" => null
3)
4)
BETWEEN クエリを処理するには、次の条件を使用できます:
1 array('Post.read_count BETWEEN ? AND ?' => array(1,10))
メモ
CakePHP が引用する数値は DB のカラムタイプによって異なります。
グループ化?:
1配列(
2 'フィールド' => 配列(
3 'Product.type'、
4 '価格としてのMIN(Product.price)'
5)、
6 'グループ' => 'Product.type'
7)
戻り値の形式は次のとおりです:
1 配列
2 (
3 [0] => 配列
4 (
5 [製品] =>
6 (
7 [タイプ] => 衣類
8)
9 [0] => 配列
10 (
)
C11 [価格] = & gt;
12)
13)
14 [1] => 配列
15 ...
DISTINCT クエリを実行する簡単な例を次に示します。 MIN()、MAX() などの他の演算子も同様の形式で使用できます。
1配列(
2 'fields' => array('DISTINCT (User.name) AS my_column_name'),
3 'order' = >array('User.id DESC')
4)
複数の条件配列をネストすることにより、非常に複雑な条件を構築できます:
1 配列(
2 'OR' => 配列(
3 array('Company.name' => 'Future Holdings'),
4 配列('Company.city' => 'CA')
5 )、
6 'AND' => 配列(
7 配列(
8 'OR' => array(
9 array('Company.status' => 'active'),
10 'NOT' => array(
11 array('Company.status' => array('inactive', 'suspended'))
12 )
13)
14)
15)
16)
対応する SQL クエリは次のとおりです:
1 `会社`.`id`、`会社`.`名前`、
を選択します
2 `会社`.`説明`、`会社`.`所在地`、
3 `会社`.`作成`、`会社`.`ステータス`、`会社`.`サイズ`
4
5 から
6つの「会社」AS「会社」
7どこ
8 ((`会社`.`名前` = 'フューチャーホールディングス')
9 または
10 (`会社`.`名前` = 'スティールメガワークス'))
11と
12 ((`会社`.`ステータス` = 'アクティブ')
13 OR (NOT (`会社`.`ステータス` IN ('非アクティブ', '一時停止'))))
サブクエリ
以下の例では、「id」、「name」、「status」列を持つ「users」テーブルがあることを前提としています。ステータスは「A」、「B」、「C」です。そして、サブクエリを使用して、ステータスが「B」とは異なるすべてのユーザーを取得したいと考えています。
これを実現するには、SQL ステートメントが返されることを除いて、find メソッドを呼び出しているのと同じように、モデル データ ソースを取得してクエリを構築するリクエストを行います。次に、式を生成し、条件配列に追加します。
1 $conditionsSubQuery['"User2"."status"'] = 'B';
2
3 $db = $this->User->getDataSource();
4 $subQuery = $db->buildStatement(
5 配列(
D 6 'フィールド' = & GT; 配列 ('"User2"."ID"'),
7 'テーブル' => $db->fullTableName($this->User),
8
9
10 'オフセット' =>
11 '結合' =>
12 '条件' => $conditionsSubQuery,
13 '注文' =>
14 'グループ' =>
15)、
16 $this->ユーザー
17 );
18 $subQuery = ' "ユーザー"."id" が入っていません (' . $subQuery . ') ';
19 $subQueryExpression = $db->expression($subQuery);
20
21 $conditions[] = $subQueryExpression;
22
23 $this->User->find('all', Compact('conditions'));
生成された SQL クエリは次のとおりです:
1選択
2 "User"."id" AS "User__id",
3 "ユーザー"."名前" AS "User__name",
4 "ユーザー"."ステータス" AS "User__status"
5 から
「ユーザー」として6人の「ユーザー」
7どこ
8 "ユーザー"."id" がありません (
9セレクト
10 "User2"."id"
11から
「User2」として 12 人の「ユーザー」
13 どこ
14 "ユーザー2"."ステータス" = 'B'
15)
また、上記の生の SQL クエリの一部を渡す必要がある場合、生の SQL を含むデータ ソース式はクエリのどの部分でも機能します。 www.2cto.com
準備されたステートメント
クエリをさらに制御する必要がある場合は、準備されたステートメントを使用できます。これにより、データベースドライバーと直接通信し、必要なカスタムクエリを渡すことができます:
1 $db = $this->getDataSource();
2 $db->fetchAll(
3 'ユーザー名 = ? かつパスワード = ? のユーザーから * を選択',
4 配列('ジョン', '12345')
5);
6 $db->fetchAll(
7 'ユーザー名 = :ユーザー名 AND パスワード = :パスワードのユーザーから * を選択',
8 array('ユーザー名' => 'ジョン','パスワード' => '12345')
9);
http://www.bkjia.com/PHPjc/477780.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/477780.html技術記事データの取得 前述したように、モデル層の役割の 1 つは、さまざまなストアからデータを取得することです。 CakePHP モデル クラスには、このデータの検索、並べ替え、ページネーションなどに役立つ多くの関数が付属しています。