如何检查 ADOdb 中模拟的准备好的语句?

发布于 2024-10-05 06:10:45 字数 864 浏览 4 评论 0原文

多年来我一直使用 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 中查找)?我试图阅读库源代码,但中途迷失了......

I've been using ADOdb for many years as my database abstraction and query caching layer. Lately I switched to prepared statements, mostly for security, and became curious about the way they are (or are not) implemented.

Quote from the documentation for the Prepare method: “Returns an array containing the original sql statement in the first array element; the remaining elements of the array are driver dependent. If there is an error, or we are emulating Prepare( ), we return the original $sql string.

Testing the statement variable with:

$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
print_r($stmt);

On connections opened with ‘mysql’ or ‘mysqli’ parameter only the original query string is returned – meaning the prepared statement is emulated, I guess. A connection opened with ‘pdo_mysql’ returns (from print_r()):

Array (
    [0] => SELECT * FROM pages WHERE id = ? 
    [1] => PDOStatement Object ([queryString]=>SELECT * FROM pages WHERE id = ?) 
) 

Can I take this as a definite proof of a real prepared statement? If not, does anybody know of a quick and dirty way to check server-side (something to look for in the query log, or maybe in MySQLProxy)? I tried to read the library source, but got lost halfway...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放血 2024-10-12 06:10:45

我可以将此作为真正准备好的陈述的明确证据吗

正如文档所述,如果您尝试使用不支持准备好的语句的驱动程序准备语句,则仅返回给定的查询,否则返回以查询作为第一个元素的数组。因此,要检查是否要模拟准备好的语句,只需检查 $stmt 是否为数组。我假设你不会尝试通过传递数组来准备,所以这个应该足够了:

$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
if(is_array($stmt)){
    //prepared
}
else{
    //emulated
}

如果你困惑为什么 mysqli 驱动程序返回 SQL,尽管 mysqli 驱动支持准备好的语句,在 drivers/adodb-mysqli.inc.php 的第 662 行中有解释>:

// Prepare() not supported because mysqli_stmt_execute does not return a recordset, but
// returns as bound variables.

Can I take this as a definite proof of a real prepared statement

As documentations says, if you try to prepare statement using driver that does not support prepared statements, only given query is returned, otherwise array with query as first element. So to check if prepared statement is going to be emulated just check if $stmt is array. I assume you wouldn't try to prepare by passing an array, so this one should be enough:

$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
if(is_array($stmt)){
    //prepared
}
else{
    //emulated
}

If you are confused why mysqli driver returns SQL despite mysqli driver supporting prepared statements, it's explained in line 662 of drivers/adodb-mysqli.inc.php:

// Prepare() not supported because mysqli_stmt_execute does not return a recordset, but
// returns as bound variables.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文