Mar*_*ies 6 php mysql pdo prepared-statement
我偶然发现了(imho相当糟糕的文档)事实,默认情况下,PHP PDO MYSQL_ATTR_DIRECT_QUERY为其MySQL驱动程序启用了标志.
这意味着它不是实际使用预准备语句,而是模拟预准备语句的行为.这意味着它使用转义值替换占位符客户端,并按原样将完整查询发送到数据库.
曾经有一个很好的理由这样做,因为在旧版本的MySQL预编译语句中会绕过查询缓存.但现在情况已经不是这样了.还有一点性能优势,因为它减少了从应用程序到数据库的往返次数,但我不确定这是值得的吗?
使用这种方法的明显缺点是我们仍然依赖于客户端转义,这通常是一个坏主意.我遇到了一些奇怪的问题,mysqli_real_escape_string过去由于某些字符集配置错误而允许无效字符进入查询.我宁愿不再有类似的事情再次发生.
我只是在这个问题上找到了半真半假和肤浅的评论(例如'是的,你可以启用'或'它会导致"问题"').寻找一个真正的原因,为什么我不打开它?在MySQL/PDO中使用实际准备好的语句无论如何都与模拟的预处理语句不兼容?
我问的部分原因是因为我们使用PHPActiverecord,它依赖于PDO.它不附带测试,我不希望它突然中断生产,因为关闭模拟的预准备语句会巧妙地改变某些边缘情况下的行为.
(作为旁注,在任何人提起之前:检查PDO::ATTR_EMULATE_PREPARES不起作用,因为它实际上没有(完全)为MySQL驱动程序实现,你必须检查PDO::MYSQL_ATTR_DIRECT_QUERY.是的,那个花了我一段时间.)
澄清:我想知道是否有充分的理由不关闭此行为.不是我不应该首先关心的原因.
该问题基于一个无效的假设:不完全支持模拟准备。(他们得到完全支持)。
事实上,MYSQL_ATTR_DIRECT_QUERY只不过是ATTR_EMULATE_PREPARES的别名。
源代码中的证明:连接处理和属性 Getter 代码和属性 Setter 代码。
setter 代码是最能说明问题的。即:
390 case PDO_MYSQL_ATTR_DIRECT_QUERY:
391 case PDO_ATTR_EMULATE_PREPARES:
392 ((pdo_mysql_db_handle *)dbh->driver_data)->emulate_prepare = Z_BVAL_P(val);
393 PDO_DBG_RETURN(1);
Run Code Online (Sandbox Code Playgroud)
有关为什么绝对应该关闭模拟准备的更多信息,请参阅此答案。
| 归档时间: |
|
| 查看次数: |
760 次 |
| 最近记录: |