Как сделать «по-уму» обработку параметров запроса и их трансформацию? контроллер:foreach( $request as $k => $v ) {
if( in_array( $k, ['limit', 'page' ] ) ) {
continue;
}
if( is_array( $v ) ) {
if( isset($v['type']) ) {
switch($v['type']) {
case "parent":
$criterias[] = new Criterion\ParentLocationId($v['val']);
break;
}
} if( isset( $v['like'] ) ) {
switch( $v['like'] ) {
case 0:
$criterias[] = new Criterion\FullText( $v['val'] );
break;
case 1:
$criterias[] = new Criterion\Field( $v['name'], Criterion\Operator::LIKE, $v['val'] . "%" );
break;
case 2:
$criterias[] = new Criterion\Field( $v['name'], Criterion\Operator::LIKE, "%" . $v['val'] . "%" );
break;
case 3:
$criterias[] = new Criterion\Field( $v['name'], Criterion\Operator::EQ, $v['val'] );
break;
}
} else {
$criterias[] = new Criterion\Field( $k, Criterion\Operator::IN, $v );
}
} else {
$criterias[] = new Criterion\Field( $k, Criterion\Operator::EQ, $v);
}
}
if( count( $criterias ) > 0 ) {
$query->filter = new Criterion\LogicalAnd( $criterias );
}
эта "лапша" проверяет каждое значения реквеста,
если значение текстового типа добавляет
$criterias[] = new Criterion\Field( $k, Criterion\Operator::EQ, $v);
т.е. сравнивание
если простой массив то
$criterias[] = new Criterion\Field( $k, Criterion\Operator::IN, $v );
если массив имеет ключ type то
$criterias[] = new Criterion\ParentLocationId($v['val']);
дальше эта лапша будет только расти, как я понимаю надо перейти на объекты
дальше надо предусмотреть чтобы другой программист мог определить в своем другом бандле своей typeswitch($v['type']) {
case "parent":
$criterias[] = new Criterion\ParentLocationId($v['val']);
и свой кастомный класс типа Criterion который надо применить в входяшему параметру реквеста
в ООП не очень силён, подскажите как мне это грамотно сделать

21 Авг 2019 в 07:05
210 +1
0
Ответы
1

Для более гибкого и расширяемого решения можно использовать паттерн фабричного метода или абстрактной фабрики.

Создайте интерфейс CriterionInterface с методом applyCriteria($request) и реализуйте его в классах-критериях, например CriterionField, CriterionParentLocationId и других. Классы-критерии будут содержать логику обработки конкретных типов запросов.

Затем создайте фабрику (например CriterionFactory), которая будет принимать параметры запроса и возвращать соответствующий объект-критерий в зависимости от типа запроса.

Примерно так:

interface CriterionInterface {
public function applyCriteria($request);
}
class CriterionFactory {
public static function createCriterion($request) {
if( isset($request['type']) ) {
switch($request['type']) {
case "parent":
return new CriterionParentLocationId($request['val']);
}
}
// Добавьте другие типы критериев здесь
}
}
class Controller {
public function processRequest($request) {
$criterias = [];
foreach( $request as $k => $v ) {
if( in_array( $k, ['limit', 'page' ] ) ) {
continue;
}
if( is_array( $v ) ) {
$criterias[] = CriterionFactory::createCriterion($v);
} else {
$criterias[] = new CriterionField( $k, Criterion\Operator::EQ, $v);
}
}
if( count( $criterias ) > 0 ) {
$query->filter = new Criterion\LogicalAnd( $criterias );
}
}
}

Такой подход позволит легко добавлять новые типы критериев, не изменяя основной логики обработки запросов. Каждый разработчик сможет создать свой собственный критерий, реализуя интерфейс CriterionInterface, и добавить его в фабрику.

20 Апр 2024 в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир