Построитель запросов "ИЛИ" в динамическом запросе - PullRequest
0 голосов
/ 15 октября 2019

Я хотел бы построить запрос с предложением «ИЛИ», и запрос получит параметр массива и не будет знать, как его элементы содержатся.

Запрос должен вернуть список содержимого, которое имееткатегория "1" или "2" (если массив $ category содержит [1,2]) и т. д. Категория является внешним ключом в объекте содержимого.

Мой репозиторий:

   public function getContentOfSomeCategories($categs)
    {
        $query = $this->createQueryBuilder('c');

        $conditions = [];
        foreach($categs as $value){
            $conditions[] = 'c.contentCategory = '.$value;
        }

        $orX = $query->expr()->orX();
        foreach ($conditions as $condition) {
            $orX->add($condition);
        }
        $query->add('where', $orX);

Я получаю сообщение об ошибке «Слишком много параметров: запрос определяет 1 параметр, а вы связываете 2».

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Начиная с версии PHP 5.6, вы, вероятно, можете использовать PHP splat ... для расширения массива до аргументов.

        $query = $this->createQueryBuilder('c');
        $expr = $query->expr();

        $conditions = [];
        $valueNo = 0;
        foreach ($categs as $value) {
            $conditions[] = $expr->eq('c.contentCategory', 'value'.$valueNo);
            $query->setParameter('value'.$valueNo, $value);
            $valueNo++;
        }
        $query->andWhere($expr->orX(...$conditions));

Отказ от ответственности: я не проверял это.

См .: https://www.php.net/manual/en/functions.arguments.php

Вы также можете использовать ... при вызовефункции для распаковки массива или переменной или литерала Traversable в список аргументов:

Редактировать:

Если ваш запрос прост, вы можете просто использовать orWhere вместо.

        $query = $this->createQueryBuilder('c');
        $expr = $query->expr();

        $valueNo = 0;
        foreach ($categs as $value) {
            $query->orWhere($expr->eq('c.contentCategory', 'value'.$valueNo));
            $query->setParameter('value'.$valueNo, $value);
            $valueNo++;
        }

Редактировать 2:

Возможно, вы даже захотите использовать вместо этого in предложение.

$query->where($expr->in('c.contentCategory', ':values'));
$query->setParameter('values', $categs);`
0 голосов
/ 15 октября 2019

Вы можете достичь этого довольно легко, ниже используется построитель выражений построителя запросов:

$queryBuilder = $this->createQueryBuilder('c');

$conditions = [];

$i = 0;

foreach ($categs as $value) {
    $i++;

    $conditions[] = $queryBuilder->expr()->eq('c.contentCategory', $i);
    $queryBuilder->setParameter($i, $value);
}

$queryBuilder->andWhere(
    $queryBuilder->expr()->orX()->addMultiple($conditions)
);

Если ваш параметр применяется ко всем, вы можете просто добавить

$queryBuilder->setParameter();

...