我在 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.