14

我目前使用 Zend_Db 来管理我的查询。我已经编写了执行如下查询的代码:

$handle->select()->from('user_id')
                   ->where('first_name=?', $id)
                   ->where('last_name=?', $lname)

假设 Zend_Db 会,我已经在没有清理输入的情况下完成了这项工作。Zend 会这样做吗?

另一个问题: Zend_Db 是否清理insert('table', $data)update查询?

谢谢。

4

7 回答 7

24

我在 Zend Framework 中编写了很多用于数据库参数和引用的代码,而我是该项目的团队负责人(直到版本 1.0)。

我试图在可能的情况下鼓励最佳实践,但我必须在易用性和易用性之间取得平衡。

请注意,您始终可以检查Zend_Db_Select对象的字符串值,以了解它是如何决定引用的。

print $select; // invokes __toString() method

您还可以使用Zend_Db_Profiler来检查由 代表您运行的 SQL Zend_Db

$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) );
    

    但是,如果您传递的参数是 type 的对象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.

    Values are parameterized, unless they are Zend_Db_Expr objects, as in insert() method.

    The $where argument is not filtered at all, so you're responsible for any SQL injection risks in that one. You can make use of the quoteInto() method to help make quoting more convenient.

于 2009-06-12T06:50:54.333 回答
5

是的。请参阅http://framework.zend.com/manual/en/zend.db.select.html。不用担心。你怀疑是对的。

于 2009-06-10T11:36:05.190 回答
2

默认情况下,当您在 SQL 查询中使用值绑定时,如下所示:

where('first_name=?', $id);

Zend_Db 使用适当的值引用来防止 SQL 注入。尽管强烈建议(通过书籍、文章、手册和自我体验)清理/过滤用户输入。Zend_Filter会很有帮助。

于 2009-06-10T17:41:42.503 回答
1

应该让你感到安全的一点是?where 子句中的标记。这些是参数,由数据库系统安全地替换为第二个参数。

于 2009-06-10T16:25:34.700 回答
1

当您在其他地方需要它(例如加入)或者您不确定它是否会被转义时,您可以随时使用$this->getAdapter()->quoteInto('type = ?',1);

于 2009-06-10T17:17:48.557 回答
0

过滤输入总是好的,因为它很可能会进入数据库以外的其他地方,并且您至少希望数据库中的数据在某个级别上是健全的。

  • Zend_Filter_Input在进的路上
  • 准备好的语句(如果不在准备好的语句中,则为 quoteInto)
  • 退出过滤器(htmlentities 等)。
于 2009-06-10T20:59:42.570 回答
0

关于这一点,当值为 NULL 时,您可以获得无效查询

$value = NULL;
$select->where('prop=?', $value);

结果:SQL 错误

于 2009-06-11T16:49:53.357 回答