为什么 PDO 不允许同名的多个占位符?

Why PDO doesn't allow multiple placeholders with the same name?

我将 PHP 和 MySQL 与 PDO 一起使用。有时我需要准备一个语句,其中一个变量(占位符)在此查询中使用了不止一次。

示例:

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 (!!!) 次单个变量的查询。每次添加占位符都需要检查很多地方的代码才可以。

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

Is there any setting or a tweak to bypass this?

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

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

The change was made for two reasons; first and foremost, if you re-use the same variable in a bind, it is possible to induce a crash when using some drivers. It’s not possible to guarantee to do the right thing, and having a way to trigger a crash can sometimes be used as an attack vector for a security exploit.

The second reason is that of portability. Some drivers would internally perform this check and error out. If you code against the drivers that don’t enforce this, then your code won’t work on those that don’t.

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