Intereting Posts
PHP CURL слишком медленный для локального хоста API Gmail: 400 плохих запросов при попытке отправить электронное письмо (код PHP) Можно ли вставить тег комментария в xml с помощью simplexml? Лучший способ кодирования специальных символов в URL-адресе PHP-перенаправление с переменными строки запроса HTTP Предпочтительный метод хранения массивов PHP (json_encode vs serialize) Самый быстрый способ удаления значения в списке, разделенном запятыми HTML в символах формы Symfony2 вместо обычного текста получение ошибки при попытке использовать созданное мной пространство имен Как написать код для многоязычия в php? Загружать несколько файлов на сервер с php, не загружая на сервер все файлы PHP Неустранимая ошибка: время передачи по ссылке удалено как проверить, не является ли поле уникальным Загрузка файла повреждена Требуется замена отрицательной замены переменной ширины

Как использовать WHERE IN с Doctrine 2

У меня есть следующий код, который дает мне ошибку:

Message: Invalid parameter number: number of bound variables does not match number of tokens 

Код:

 public function getCount($ids, $outcome) { if (!is_array($ids)) { $ids = array($ids); } $qb = $this->getEntityManager()->createQueryBuilder(); $qb->add('select', $qb->expr()->count('r.id')) ->add('from', '\My\Entity\Rating r'); if ($outcome === 'wins') { $qb->add('where', $qb->expr()->in('r.winner', array('?1'))); } if ($outcome === 'fails') { $qb->add('where', $qb->expr()->in('r.loser', array('?1'))); } $qb->setParameter(1, $ids); $query = $qb->getQuery(); //die('q = ' . $qb); return $query->getSingleScalarResult(); } 

Данные (или $ ids):

 Array ( [0] => 566 [1] => 569 [2] => 571 ) 

Результат DQL:

 q = SELECT COUNT(r.id) FROM \My\Entity\Rating r WHERE r.winner IN('?1') 

Изучая эту проблему, я нашел то, что будет важно для всех, кто работает в этой же проблеме и ищет решение.

Из исходного сообщения следующая строка кода:

 $qb->add('where', $qb->expr()->in('r.winner', array('?1'))); 

Приобретение именованного параметра в качестве массива вызывает проблему с номером связанного параметра. Удалив его из упаковки массива:

 $qb->add('where', $qb->expr()->in('r.winner', '?1')); 

Эта проблема должна быть исправлена. Возможно, это была проблема в предыдущих версиях Doctrine, но она исправлена ​​в самых последних версиях версии 2.0.

Самый простой способ сделать это – связать сам массив как параметр:

 $queryBuilder->andWhere('r.winner IN (:ids)') ->setParameter('ids', $ids); 

и для завершения строкового решения

 $qb->andWhere('foo.field IN (:string)'); $qb->setParameter('string', array('foo', 'bar'), \Doctrine\DBAL\Connection::PARAM_STR_ARRAY); 

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

 $ids = array(...); // Array of your values $qb->add('where', $qb->expr()->in('r.winner', $ids)); 

http://groups.google.com/group/doctrine-dev/browse_thread/thread/fbf70837293676fb

Лучший способ сделать это – особенно если вы добавляете более одного условия – это:

 $values = array(...); // array of your values $qb->andWhere('where', $qb->expr()->in('r.winner', $values)); 

Если ваш массив значений содержит строки, вы не можете использовать метод setParameter со впалой строкой, потому что ваши кавычки будут экранированы!

Вот как я его использовал:

 ->where('b.status IN (:statuses)') ->setParameters([ 'customerId' => $customerId, 'storeId' => $storeId, 'statuses' => [Status::OPEN, Status::AWAITING_APPROVAL, Status::APPROVED] ]); 

Нашел, как это сделать в 2016 году: https://redbeardtechnologies.wordpress.com/2011/07/01/doctrine-2-dql-in-statement/

Цитата:

Вот как это сделать правильно:

 $em->createQuery(“SELECT users FROM Entities\User users WHERE users.id IN (:userids)”) ->setParameters(array('userids' => $userIds)); 

Параметр SetParameters примет массив и соответствующим образом развяжет его для использования в инструкции «IN».

Я знаю, что пример OP использует DQL и построитель запросов, но я наткнулся на это, ища, как это сделать с контроллера или вне класса репозитория, так что, возможно, это поможет другим.

Вы также можете сделать WHERE IN от контроллера таким образом:

 // Symfony example $ids = [1, 2, 3, 4]; $repo = $this->getDoctrine()->getRepository('AppBundle:RepoName'); $result = $repo->findBy([ 'id' => $ids ]); 

Я предпочитаю:

 $qb->andWhere($qb->expr()->in('t.user_role_id', [ User::USER_ROLE_ID_ADVERTISER, User::USER_ROLE_ID_MANAGER, ])); 
 ->where($qb->expr()->in('foo.bar', ':data')) ->setParameter('participants', $data); 

Также работает с:

  ->andWhere($qb->expr()->in('foo.bar', ':users')) ->setParameter('data', $data); 

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

Следующие работали для меня:

http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/dql-doctrine-query-language.html#where-clause

 ->andWhereIn("[fieldname]", [array[]]) 

Пример данных массива (работает со строками и целыми числами):

 $ids = array(1, 2, 3, 4); 

Пример запроса (адаптируйте туда, где он вам нужен):

 $q = dataTable::getInstance() ->createQuery() ->where("name = ?",'John') ->andWhereIn("image_id", $ids) ->orderBy('date_created ASC') ->limit(100); $q->execute();