Intereting Posts
Вызов Perl-скрипта из PHP и передача в переменных, а также использование имени переменной perl-скрипта IP для страны в PHP Получить имя класса из файла file_get_contents синхронный или асинхронный Перезагрузить страницу после успеха ajax C # RSA Encrypt -> PHP RSA Decrypt Проблемы с вращением и изменением размера больших изображений Добавить прослушиватель событий для создания элемента, добавленного прослушивателем событий Как я могу создать в целом эстетически приятный диапазон цветов линейного графика (неизвестный номер), начиная с базового цвета? Как продолжать проверку файла до его появления, а затем предоставить ссылку на него phpmailer – Следующая ошибка SMTP: данные не принимаются Передача массива PHP через jQuery Ajax Строгие стандарты: только переменные должны передаваться по ссылке в m_auth Работа по Soundcloud 500×500 по умолчанию Подключения PHP к MySQL SSL

Сложное предложение WHERE с Zend_Db с использованием нескольких операторов AND OR

Я хочу создать это сложное предложение WHERE в Zend_Db:

SELECT * FROM 'products' WHERE status = 'active' AND ( attribute = 'one' OR attribute = 'two' OR [...] ) ; 

Я пробовал это:

 $select->from('product'); $select->where('status = ?', $status); $select->where('attribute = ?', $a1); $select->orWhere('attribute = ?', $a2); 

и которые производят:

 SELECT `product`.* FROM `product` WHERE (status = 'active') AND (attribute = 'one') OR (attribute = 'two') ; 

Я выяснил один способ создания этой работы, но я чувствовал, что это своего рода «обман», используя PHP, чтобы сначала объединить предложения «ИЛИ», а затем объединить их с помощью предложения Zend_Db where (). PHP-код:

 $WHERE = array(); foreach($attributes as $a): #WHERE[] = "attribute = '" . $a . "'"; endforeach; $WHERE = implode(' OR ', $WHERE); $select->from('product'); $select->where('status = ?', $status); $select->where($WHERE); 

Это создало то, что я искал. Но мне любопытно, есть ли «официальный» способ получить этот сложный оператор WHERE (который действительно не слишком сложный, просто добавив некоторые скобки) с использованием инструмента Zend_Db, вместо того, чтобы сначала комбинировать его в PHP.

Ура!

Это был бы «официальный» способ получить скобки в соответствии с указанными (см. Пример № 20 в документации Zend_Db_Select ):

 $a1 = 'one'; $a2 = 'two'; $select->from('product'); $select->where('status = ?', $status); $select->where("attribute = $a1 OR attribute = $a2"); 

Итак, то, что вы делаете, кажется разумным, учитывая, что вы не знаете, сколько атрибутов у вас есть раньше времени.

Если вы используете выбранный ответ, вам нужно будет запомнить значения перед построением запроса для защиты от SQL-инъекции.

Другой вариант, который использует Zend Db Select для создания запроса, а также цитирует значения, должен был сделать это в 2 этапа:

 /// we just use this select to create the "or wheres" $select1->from('product'); foreach($attributes as $key => $a) { if ($key == 0) { /// we don't want "OR" for first one $select1->where("attribute = ?", $a); } else { $select1->orWhere("attribute = ?", $a); } } /// now we construct main query $select2->from('product'); $select2->where('status = ?', $status); $select2->where(implode(' ', $select1->getPart('where'))); 

Таким образом Zend Db Select выполняет все генерирование SQL. Старый вопрос, но, надеюсь, эта идея может пригодиться кому-то с аналогичной проблемой.

Я использую это решение и, похоже, работает как нужно.

 $select->from('product'); $select->where('status = ?', $status); $select->where('(attribute = ?', $a1); $select->orWhere('attribute = ?)', $a2); 

Если ваш атрибут является одним и тем же столбцом таблицы, и вы хотите проверить его на одно из нескольких значений, вы можете использовать IN:

 $select->from('product'); $select->where('status = ?', $status); $select->where('attribute IN (?)', [$a1, $a2, ...]); 

или

 $select->where('attribute IN (:someName)'); $select->setParameter('someName', [$a1, $a2, ...]); 

В противном случае я не вижу альтернативы вышеизложенному решению с "attribute = $a1 OR attribute = $a2"