我多年来一直使用ADOdb作为我的数据库抽象和查询缓存层。最近我转而使用预备语句,主要是出于安全考虑,并对它们实现(或未实现)的方式感到好奇。
引用Prepare方法的文档:“返回包含第一个数组元素中原始sql语句的数组;数组的其余元素依赖于驱动程序。如果有错误,或者我们正在模拟Prepare(),我们将返回原始的$ sql字符串。“
使用以下语句测试语句变量:
$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
print_r($stmt);
在使用'mysql'或'mysqli'参数打开的连接上,只返回原始查询字符串 - 这意味着我会猜测准备好的语句是模拟的。用'pdo_mysql'打开的连接返回(来自print_r()):
Array (
[0] => SELECT * FROM pages WHERE id = ?
[1] => PDOStatement Object ([queryString]=>SELECT * FROM pages WHERE id = ?)
)
我可以将此作为真实准备陈述的明确证据吗?如果没有,是否有人知道检查服务器端的快速和脏的方式(在查询日志中查找的内容,或者在MySQLProxy中查找)?我试图读取库源,但中途丢失了......
答案 0 :(得分:0)
我可以将此作为真实准备陈述的明确证据
正如文档所述,如果您尝试使用不支持预准备语句的驱动程序来准备语句,则只返回给定的查询,否则将查询作为第一个元素的数组。因此,要检查是否要模拟预准备语句,只需检查$stmt
是否为数组。我假设您不会尝试通过传递数组来准备,所以这个应该足够了:
$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
if(is_array($stmt)){
//prepared
}
else{
//emulated
}
如果您感到困惑,为什么 mysqli 驱动程序返回SQL mysqli driver supporting prepared statements,则在 drivers / adodb-mysqli.inc.php 的第662行中对此进行了解释:< / p>
// Prepare() not supported because mysqli_stmt_execute does not return a recordset, but
// returns as bound variables.