我目前使用Zend_Db来管理我的查询。 我已经编写了代码,可以执行如下所示的查询:
$handle->select()->from('user_id')
->where('first_name=?', $id)
->where('last_name=?', $lname)
我假设Zend_Db会在没有清理输入的情况下完成此操作。 Zend会这样做吗?
另一个问题:
Zend_Db会清理insert('table', $data)
和update
个查询吗?
感谢。
答案 0 :(得分:24)
我在Zend Framework中编写了很多数据库参数和引用的代码,而我是该项目的团队负责人(最高版本为1.0)。
我试图在可能的情况下鼓励最佳实践,但我必须在易用性方面取得平衡。
请注意,您始终可以检查Zend_Db_Select
对象的字符串值,以了解它是如何决定引用的。
print $select; // invokes __toString() method
此外,您可以使用Zend_Db_Profiler
检查由Zend_Db
代表您运行的SQL。
$db->getProfiler()->setEnabled(true);
$db->update( ... );
print $db->getProfiler()->getLastQueryProfile()->getQuery();
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams();
$db->getProfiler()->setEnabled(false);
以下是您具体问题的一些答案:
Zend_Db_Select::where('last_name=?', $lname)
适当引用值。虽然“?
”看起来像参数占位符,但在此方法中,参数实际上是适当引用并进行插值的。所以它不是一个真正的查询参数。实际上,以下两个语句产生与上述用法完全相同的查询:
$select->where( $db->quoteInto('last_name=?', $lname) );
$select->where( 'last_name=' . $db->quote($lname) );
但是,如果传递的参数是Zend_Db_Expr
类型的对象,则不会引用它。您负责SQL注入风险,因为它是逐字插入的,以支持表达式值:
$select->where('last_modified < ?', new Zend_Db_Expr('NOW()'))
该表达式中需要引用或分隔的任何其他部分是您的责任。例如,如果您将任何PHP变量插入到表达式中,则安全是您的责任。如果列名是SQL关键字,则需要使用quoteIdentifier()
自行分隔。例如:
$select->where($db->quoteIdentifier('order').'=?', $myVariable)
Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )
表名称和列名称是分隔的,除非您关闭AUTO_QUOTE_IDENTIFIERS
。
将值参数化为真实查询参数(未插入)。除非该值是Zend_Db_Expr
对象,在这种情况下,它是逐字插值的,因此您可以插入表达式或NULL
或其他任何内容。
Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )
表名称和列名称是分隔的,除非您关闭AUTO_QUOTE_IDENTIFIERS
。
值是参数化的,除非它们是Zend_Db_Expr
个对象,如insert()
方法。
$where
参数根本没有被过滤,所以你要对那个中的任何SQL注入风险负责。您可以使用quoteInto()
方法来帮助引用更方便。
答案 1 :(得分:5)
是。见http://framework.zend.com/manual/en/zend.db.select.html。别担心。你是对的持怀疑态度。
答案 2 :(得分:2)
默认情况下,在SQL查询中使用值绑定时,如下所示:
where('first_name=?', $id);
Zend_Db使用适当的值引用来防止SQL注入。虽然强烈建议(通过书籍,文章,手册和自我体验)清理/过滤用户输入。 Zend_Filter非常有用。
答案 3 :(得分:1)
应该让你觉得安全的是?在where子句中标记。这些参数由数据库系统安全地替换为第二个参数。
答案 4 :(得分:1)
如果您在其他地方需要它(例如在加入中)或者您不确定它是否会被转义,那么您可以随时使用$this->getAdapter()->quoteInto('type = ?',1);
答案 5 :(得分:0)
过滤输入始终是好的,因为它可能会在除了数据库之外的其他地方,并且您至少需要在某个级别的数据库中获得理智的数据。
Zend_Filter_Input
正在进行中答案 6 :(得分:0)
有一点是,当值为NULL时,您可以获得无效的查询
$value = NULL;
$select->where('prop=?', $value);
结果:SQL错误