Используйте именованные заполнители в PHP ActiveRecord - PullRequest
0 голосов
/ 04 октября 2019

Я работаю над API с FlightPHP и PHPActiveRecord, который возвращает массив отчетов, необязательно фильтруемых по параметрам строки запроса URL.

$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 года и была закрыта.

Есть ли другой способ элегантной фильтрации запроса с необязательными параметрами?

- EDIT -

Я работал над обходным решением с позиционными заполнителями, которое работает без именованных заполнителей. Я все еще думаю, что версия с именованным заполнителем выглядит чище и понятнее.

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))];
}
...