PDO 是不是仍在为 MySQL 模拟准备好的语句?

Posted

技术标签:

【中文标题】PDO 是不是仍在为 MySQL 模拟准备好的语句?【英文标题】:Is PDO still emulating prepared statements for MySQL?PDO 是否仍在为 MySQL 模拟准备好的语句? 【发布时间】:2020-03-26 20:42:26 【问题描述】:

PDO 是否仍在为 mysql 模拟准备好的语句?这已经在this 中回答了,但答案是多年前给出的,它很大,所以这里引用:

现在,值得注意的是,您可以通过禁用 emulated 准备好的语句:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

这通常会产生一个真正的准备好的语句(即数据 从查询中以单独的数据包发送)。然而,成为 意识到 PDO 将默默地回退到模拟语句 MySQL不能原生准备:它可以列出的那些 手册,但要注意选择合适的服务器版本)。

我是通过

连接的
$conn = new PDO("mysql:dbname=$dbname;host=$dbhost;charset=utf8",$dbuser,$dbpasswd);

有没有办法切换到mysqli?如果是这样,它会使用真正的准备吗?

using two versions php 7.2.19 and php 5.6
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using  EditLine wrapper

【问题讨论】:

“有没有办法切换到 mysqli?” - 如果你问,是否可以重写代码以使用 MySQLi 而不是 PDO,那么答案是肯定的… 你为什么不像引用中所说的那样禁用仿真? @YourCommonSense 因为在使用 mysql 时禁用仿真回退到仿真 【参考方案1】:

您所指的答案更像是一个可怕的故事,而不是真正的帮助。如果您阅读底部的细则,它表示使用实际的软件版本是可以的(实际是指 2010 年之后发布的)。

因此,您可以看出,在安全方面,是否模拟准备好的语句没有区别。因此,您的问题的答案并不那么重要。

此外,您错误地理解了其中的某个陈述。

但是,请注意 PDO 会默默地回退到模拟 MySQL 本身无法准备的语句

这并不意味着 mysql 根本不支持本机准备好的语句。这意味着只有某些特定类型的查询 mysql 不支持准备好的语句。对于此类查询,您没有太多选择,因此再次无关紧要。

说清楚

当未设置任何选项时,PDO 仍会模拟 MySQL 的预准备语句默认情况下。 对于最常用的查询类型,例如 SELECT、INSERT、UPDATE 等,如果明确告知使用本机语句,PDO 不会模拟为 MySQL 准备好的语句。顺便说一句,the list of supported statements is quite inclusive 由于此行为是在服务器端决定的,因此将 PHP API 从 PDO 更改为 mysqli 将无济于事。 对于一些很少使用的查询类型,它可能会默默地回退到模拟语句,但这既不是安全问题,也不是您有选择的余地。

总结一下:

为方便起见,请禁用模拟作为连接选项。意味着您必须将当前的单线连接更改为成熟的PDO connection script,我建议将其作为规范示例,然后继续。

【讨论】:

【参考方案2】:

根据我对文档的理解,PDO 似乎总是会尝试使用本机准备好的语句,除非驱动程序不支持它们,或者如果您使用 ATTR_EMULATE_PREPARES 明确声明您想要它

文档:

准备好的语句非常有用,以至于它们是唯一的功能 PDO 将模拟不支持它们的驱动程序。这确保 应用程序将能够使用相同的数据访问范例 无论数据库的功能如何。

还有:

PDO::ATTR_EMULATE_PREPARES 启用或禁用准备好的模拟 陈述。一些驱动程序不支持本机准备语句或 对他们的支持有限。使用此设置强制 PDO 总是模拟准备好的语句(如果 TRUE 和模拟准备是 由驱动程序支持),或尝试使用本机准备好的语句 (如果为假)。它总是会退回到模仿准备好的 如果驱动程序无法成功准备当前查询,则声明。

【讨论】:

阅读引用的有问题的文字,它以“值得注意”开头

以上是关于PDO 是不是仍在为 MySQL 模拟准备好的语句?的主要内容,如果未能解决你的问题,请参考以下文章

从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?

用 PDO 和准备好的语句替换 mysql_* 函数

mysql永久准备语句

从 PDO 准备语句中检索(或模拟)完整查询

mysql性能中的PDO

PDO - 使用准备好的语句[重复]