У меня есть функция, подобная следующей:
public function foo ($cities = array('anaheim', 'baker', 'colfax') ) { $db = global instance of Zend_Db_Adapter_Pdo_Mysql... $query = 'SELECT name FROM user WHERE city IN ('.implode(',',$cities).')'; $result = $db->fetchAll( $query ); }
Это отлично работает, пока кто-то не передаст $ города в виде пустого массива.
Чтобы предотвратить эту ошибку, я логически нарушил такой запрос:
$query = 'SELECT name FROM user'; if (!empty($cities)) { $query .= ' WHERE city IN ('.implode(',',$cities).')'; }
но это не очень элегантно. Я чувствую, что должен быть лучший способ фильтрации по списку, но я не уверен, как это сделать. Любой совет?
По крайней мере, используйте метод quote
…
if ($cities) { $query .= sprintf('WHERE city IN (%s)', implode(',', array_map(array($db, 'quote'), $cities))); }
или, в идеале, построить запрос с помощью Zend_Db_Select …
$select = $db->select()->from('user', 'name'); if ($cities) { foreach ($cities as $city) { $select->orWhere('city = ?', $city); } }
Если вы в конечном итоге используете объект select, метод ->where()
будет обрабатывать массивы для вас. Все еще нужно проверить, есть ли элементы в массиве, но это делает его более чистым подходом …
$select = $db->select()->from('user', 'name'); if ($cities) { $select->where('city IN (?)', $cities); }
Итак, вы знаете, что из Zend Docs Zend_Db_Adapter :: quote «Если массив передан как значение, значения массива цитируются *, а затем возвращаются как строка, разделенная запятыми».
Таким образом, вы можете сделать это, которое также правильно указано:
if ($cities) $query .= 'WHERE city IN ({$db->quote($cities}) ';
Мне нравится 1-лайнер 🙂