2010-10-05 72 views
4

我有类似下面的功能:PHP破灭阵列产生在MySQL标准

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).')'; 
} 

但这是不是很优雅。我觉得应该有一个更好的方式来过滤列表,但我不知道如何。有什么建议?

+3

这如果用户提交包含'''(SQL注入一个城市也将打破)或逗号...你需要将它们包装在''s – 2010-10-05 21:24:37

+0

这样做完全没问题。如果没有城市,你不需要'WHERE'子句...... – 2010-10-05 21:25:05

+2

对我来说看起来很好,但是你可以使用很多类中的一个来制作精美的准备好的查询。至少,逃脱你的弦乐! http://php.net/manual/en/function.mysql-real-escape-string.php – Brad 2010-10-05 21:26:23

回答

3

至少使用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); 
    } 
} 
7

如果你最终使用选择对象->where()方法实际上会为你处理数组。还需要进行检查,看是否有数组中的项,但是这使得它更简洁的方法...

$select = $db->select()->from('user', 'name'); 

if ($cities) { 
    $select->where('city IN (?)', $cities); 
} 
0

所以,你知道,从Zend_Db_Adapter对象Zend的文档::报价 “如果一个数组传递作为值,数组值被引用为 *,然后作为逗号分隔的字符串返回。“

所以,你可以做到这一点也被引用正确:

if ($cities) $query .= 'WHERE city IN ({$db->quote($cities}) '; 

我爱1派:)