オプションで url クエリ文字列パラメーターを介してフィルター処理されたレポートの配列を返す FlightPHP と PHPActiveRecord を使用した API に取り組んでいます。
$allowed = ['author' => 'author_id', 'owner' => 'owner_id'];
$options = build_options(Flight::request(), $allowed);
$reports = Report::all($options);
メソッド build_options は、すべてのクエリ オプションを含む配列を作成します。この場合、これらの列を削除する WHERE 句は許可されておらず、渡されなかったパラメーターは無視されます。
function build_options($request, $allowed) {
$clauses = array_map(function($column, $value) {
return "($column = :$value OR :$value IS NULL)";
}, $allowed, array_keys($allowed));
$where = implode($clauses, ' AND ');
$params = array_intersect_key($request->query->getData(), $allowed);
return ['conditions' => [$where, $params]];
}
この関数は、次のような WHERE 句を作成します。
(author_id = :author OR :author IS NULL) AND (owner_id = :owner OR :owner IS NULL)
しかし、PHPActiveRecord は名前付きプレースホルダーを受け入れないようです。これについて尋ねる GitHub の唯一の問題は 2010 年のものであり、クローズされました。
オプションのパラメーターを使用してクエリをエレガントにフィルター処理する他の方法はありますか?
- 編集 -
名前付きプレースホルダーなしで機能する位置プレースホルダーを使用した回避策に取り組みました。名前付きのプレースホルダーを使用したバージョンは、よりクリーンで理解しやすいと思います。
function build_options($request, $allowed) {
$params = array_intersect_key($request->query->getData(), $allowed);
$clauses = array_map(function($param) use ($allowed) {
return "$allowed[$param] = ?";
}, array_keys($params));
$where = implode($clauses, ' AND ');
return ['conditions' => array_merge([$where], array_values($params))];
}