ホームページ  >  記事  >  PHPフレームワーク  >  ThinkPHP: データクエリの基本原則

ThinkPHP: データクエリの基本原則

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼転載
2019-12-16 17:46:263040ブラウズ

ThinkPHP: データクエリの基本原則

この記事に含まれるデータ クエリのいくつかの基本原則をプロジェクト仕様に組み込むようにしてください。これは公式が推奨するベスト プラクティスでもあります。その前に、以前のブログ「Db クラスとモデルの正しい使用姿勢を本当に理解していますか?」を読んでいただければ幸いです。

配列条件付きクエリは使用しないでください

混乱を招くクエリ構文のほとんどは配列クエリの使用によって引き起こされており、5.1 での配列条件付きクエリの使用法は次のとおりです。 5.0 と同じ 完全に異なります。5.0 の配列クエリ方法に慣れている場合は、「5.1 の配列オブジェクト クエリの使い方を教えます」の記事を読むことをお勧めします。

次は、多くの初心者が犯しがちなクエリの間違いである可能性があります。

$where['id'] = ['in', '1,2,3'];
User::where($where)->select();

明らかに、このクエリの考え方は古いバージョンの影響を深く受けています。バージョン 5.0 と比較して、バージョン 5.1 のクエリ構文はよりオブジェクト指向になっており、正しい使用法は次のとおりです。

$where['id'] = [1,2,3];
User::where($where)->select();

おそらく、PHP 配列は非常に使いやすいため、多くの人が配列クエリ条件を楽しんでいます (またはオブジェクトについて心配していますか?)。ただし、クエリ ビルダーを正しく使用し、モデルの関連機能と連携すると、クエリ ロジックがより明確になり、保守が容易になります。

さらに、より複雑なクエリ条件では、次のクエリの使用法のように、配列を使用してクエリを完了することはできません。

User::where('id', '>', 100)
    ->whereOr(&#39;id&#39;, &#39;<&#39;, 10)
    ->where(&#39;name&#39;, &#39;like&#39;, &#39;think%&#39;)
    ->whereColumn(&#39;name&#39;, &#39;nickname&#39;)
    ->when(&#39;80&#39;== $condition, function ($query) {
        $query->where(&#39;score&#39;, &#39;>&#39;, 80)->limit(10);
    })->select();

したがって、5.1 での配列クエリの使用法を知らない限り、配列条件クエリは使用しないようにしてください。

文字列クエリ条件の安全な使用

文字列クエリ条件を使用する場合、外部変数がある場合は、必ずパラメータ バインディングを使用し、できれば whereRaw メソッドを使用してください。他のクエリ ビルダー メソッドと組み合わせて使用​​できます。

User::whereRaw("id = :id AND name = :name", [
        &#39;id&#39; => [$id, \PDO::PARAM_INT] , 
        &#39;name&#39; => $name
    ])->where(&#39;status&#39;, 1)
    ->order(&#39;id&#39;, &#39;desc&#39;)
    ->select();

パフォーマンスをより重視する一部のクエリの場合は、クエリまたは実行メソッドを直接使用することもできますが、パラメータの安全性にも注意し、さまざまなデータベースの移植の問題も考慮する必要があります。

Db::query("select * from think_user where id=? AND status=?", [8, 1]);
Db::execute("update think_user set name=:name where status=:status", [&#39;name&#39; => &#39;thinkphp&#39;, &#39;status&#39; => 1]);

SQL 関数を使用するクエリには Raw メカニズムを使用する

クエリに SQL 関数が含まれる場合は、whereRaw (または whereExp)、orderRaw、または fieldRaw メソッドを使用してください。

User::whereExp(&#39;nickname&#39;, "= CONCAT(name, &#39;-&#39;, id)")
    ->orderRaw("field(name,&#39;thinkphp&#39;, &#39;kancloud&#39;)")
    ->fieldRaw(&#39;id,SUM(score)&#39;)
    ->select();

クロージャーは適切に使用しますが、乱用しないでください

クロージャー クエリにはクエリ コンストラクター内で特別な用途がありますが、必要な場合を除いて乱用する必要はありません。 。

クロージャ クエリの一般的な使用シナリオには次のようなものがあります。

クロージャは通常、条件付きクエリのセットを表すために条件付きクエリで使用されます。

User::when($condition, function ($query) {
    // 满足条件后执行
    $query->where(&#39;score&#39;, &#39;>&#39;, 80)->limit(10);
}, function ($query) {
    // 不满足条件执行
    $query->where(&#39;score&#39;, &#39;>&#39;, 60);
})->select();

クロージャは一部のサブクエリでよく使用されます。

User::whereIn(&#39;id&#39;, function ($query) {
    $query->table(&#39;profile&#39;)
        ->where(&#39;name&#39;, &#39;like&#39;, &#39;think%&#39;)
        ->field(&#39;id&#39;);
})->select();

一連の閉じたクエリ条件を生成する

User::where(&#39;id&#39;, &#39;>&#39;, 100)
    ->whereOr(function($query) {
        $query->where(&#39;name&#39;, &#39;like&#39;, &#39;think%&#39;)
        ->whereColumn(&#39;name&#39;, &#39;nickname&#39;);
    })->select();

このクエリの使用法では、クロージャ内のクエリ条件が両側に括弧を付けて追加され、閉じたクエリ条件になります。

関連するプリロード クエリの多くでは、クロージャを使用して関連データをフィルタリングできます。

User::with([&#39;profile&#39; => function($query) {
$query->field(&#39;user_id,email,phone&#39;);
}])->select([1,2,3]);

クエリ条件を再利用してみてください

すべてのクエリ条件は 1 か所で定義し、モデル メソッド (特に Don) にカプセル化するなど、複数の場所で再利用する必要があります。一連の複雑なクエリ条件をコントローラー コードに直接書き込まないでください。そうしないと、ビジネスが調整された後、世界中の検索コードがクエリ条件を変更するという悪夢が発生することになります。

公式マニュアルやいくつかのチュートリアルで、コントローラーにクエリ条件を直接カプセル化する多くの方法を見たことがあるかもしれませんが、それは使用方法を示す便宜のためだけであり、お勧めできません。

一部の中大規模アプリケーション アーキテクチャ設計では、モデルは通常、データ層、ロジック層、サービス層に分割されており、コントローラーはサービス層のメソッドのみを呼び出します。クエリ ロジックは基本的にロジック層にカプセル化され、データ層はモデルのさまざまな定義を行うだけです。

単純なアプリケーションでは、PHP の Trait メカニズムを使用してコード再利用メカニズムを実装することもできます。

クエリ スコープまたはサーチャーを使用してクエリを簡素化する

モデル クエリを使用する場合は、クエリ条件をクエリ スコープまたはサーチャー メソッドにカプセル化するようにしてください。範囲とサーチャーの違いは、クエリ範囲の方が (複数のフィールド) クエリ条件の定義に適しているということです。複数のクエリ範囲を呼び出したい場合は、複数回呼び出す必要がありますが、サーチャーはクエリ条件の定義に適しています。フィールド (実際には絶対ではありません) クエリ条件の場合、withSearch メソッドを 1 回呼び出すだけで済みます。

クエリ スコープとサーチャーの使用例。

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    public function scopeVip($query)
    {
        $query->where(&#39;user_type&#39;, &#39;vip&#39;)
            ->where(&#39;status&#39;, 1)
            ->field(&#39;id,name&#39;);
    }
    
    public function searchAgeAttr($query, $age)
    {
        $query->where(&#39;age&#39;,&#39;>&#39;,$age);
    }    
    
    public function searchScoreAttr($query, $score)
    {
        $query->where(&#39;score&#39;,&#39;<=&#39;,$score)->where(&#39;score&#39;, &#39;>&#39; ,0);
    }    
}

コントローラ コード

<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
class index extends Controller
{
    public function index(Request $request)
    {
        // 查询VIP会员
        User::vip()->select();
        // 查询年龄和分数
        User::withSearch([&#39;age,&#39;score&#39;&#39;], $request->param())->select();
    }
}

コントローラ コードでは、ビジネス ロジック自体にのみ焦点を当てており、このロジック内のクエリ条件に注意を払う必要はありません。サーチャーとクエリ範囲の詳細については、公式マニュアルを参照してください。

PHP 中国語 Web サイトには、無料の ThinkPHP 入門チュートリアル が多数あり、誰でも学習することができます。

この記事は https://blog.thinkphp.cn/833794

から転載しています。

以上がThinkPHP: データクエリの基本原則の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はthinkphp.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。