为啥 PDO 不允许具有相同名称的多个占位符?

Posted

技术标签:

【中文标题】为啥 PDO 不允许具有相同名称的多个占位符?【英文标题】:Why PDO doesn't allow multiple placeholders with the same name?为什么 PDO 不允许具有相同名称的多个占位符? 【发布时间】:2017-07-03 19:14:06 【问题描述】:

我正在使用 php,以及带有 PDO 的 mysql。有时我需要准备一个语句,其中一个变量(占位符)在此查询中多次使用。

例子:

SELECT * FROM messages WHERE from_id = :user OR to_id = :user

但是,如果我尝试准备此语句,则会出现错误,因此我需要以如下方式执行此操作:

SELECT * FROM messages WHERE from_id = :user1 OR to_id = :user2

要调用这个语句,我需要一个这样的数组:

array('user1'=>$user_id, 'user2'=>$user_id);

对我来说这看起来很愚蠢!为什么 MySQL(PDO?)不允许我多次使用一个占位符并强迫我使用需要更多控制的额外变量?!

如果查询相对简单(就像我在上面发布的那样),这可以很容易地处理,但是现在我构建了一个查询,其中包含 5 次(!!!)使用单个变量。每次添加占位符时,我都需要在很多地方检查代码以使其正常。

是否有任何设置或调整可以绕过这个?

【问题讨论】:

【参考方案1】:

是否有任何设置或调整可以绕过这个?

是的,有。 You can turn emulation mode ON 并且能够多次使用同一个占位符。

因此,只有在关闭仿真时才会观察到所描述的行为。我真的不明白为什么会这样,但下面是 Wez Furlong(PDO 的作者)的解释:

做出改变有两个原因;首先,如果您在绑定中重复使用相同的变量,则在使用某些驱动程序时可能会导致崩溃。无法保证做正确的事情,并且有办法触发崩溃有时可以用作安全漏洞的攻击媒介。

第二个原因是便携性。一些驱动程序会在内部执行此检查并输出错误。如果您针对不强制执行此操作的驱动程序进行编码,那么您的代码将不适用于不执行此操作的驱动程序。

http://paul-m-jones.com/archives/243#comment-740

【讨论】:

谢谢你,YCS!我最好避免使用仿真,因为准备好的语句执行起来应该更慢。对吗? 嗯,仿真模式实际上更快,但我不会说差异有任何显着性。上面的链接是我的文章,我在其中讨论了每种模式的所有优缺点 更快?!哇,出乎意料的事情......在这种情况下,我会去寻找关于这个的阅读......谢谢! @Your 作为另一个赞成/反对者,您不应该添加准备好的语句可以多次使用,并且在本机使用时应该明显更快,因为数据库实际上有机会解析查询一次就可以重复使用? @deceze 谢谢!确实,很明显,我忽略了这个重要的特性(尽管在另一章中提到过)。添加了一个提及。

以上是关于为啥 PDO 不允许具有相同名称的多个占位符?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 返回 PDO 占位符名称

一页中的多个 Summernote 所见即所得编辑器具有相同的占位符

在 PDO 中的执行函数中将 NULL 值绑定到具有关联数组的命名占位符的问题

在 HTML5 中不允许使用多行占位符的理由是啥?

将 PDO 与 PostgreSQL 一起使用时如何忽略问号作为占位符

Java实现JSON{参数}占位符名称替换指定的多个变量值