【问题标题】:How does the PDO prepared statements works “inside”?PDO 准备好的语句如何在“内部”工作?
【发布时间】:2016-03-08 00:10:26
【问题描述】:

准备好的语句很有用,因为准备“模板”来添加数据可以防止 SQL 注入,我的问题是,这怎么可能?

准备好的语句如何真正起作用?

在我编写查询、绑定参数并执行查询后,会发生什么?

我认为查询中没有“插入”参数,在这种情况下,准备好的语句的效果会失败......也许它使用特殊的分隔符来检测查询中数据的开始和结束。如果这是正确的,它们是什么?

【问题讨论】:

    标签: php mysql database pdo prepared-statement


    【解决方案1】:

    这完全取决于使用的PDO适配器是否可以模拟prepares(sqlsrv就是这样一个例子)或者适配的RDBMS是否确实支持prepared statements,在这种情况下,实际处理的是语句的准备和执行由客户端(或者在某些情况下甚至是服务器)。


    编辑:

    如果您对特定 PDO 适配器(可能是 pdo_mysql)如何处理此问题感兴趣,请查看源代码:https://github.com/php/php-src/blob/master/ext/pdo_mysql/mysql_statement.c

    【讨论】:

    • 如果引擎是mysql的话,语句的准备和执行由服务器完成。我不知道其他引擎是否以不同方式处理它,但我猜大部分时间是服务器。
    【解决方案2】:

    具体行为取决于。例如,PDO 中的 MySQL 驱动程序可以根据PDO::ATTR_EMULATE_PREPARES attribute 的值做两件完全不同的事情:

    启用或禁用准备好的语句的模拟。有些司机会 不支持本机准备好的语句或对 他们。使用此设置强制 PDO 始终模拟准备好的 语句(如果为 TRUE),或者尝试使用本机准备好的语句(如果 错误的)。它总是会退回到模拟准备好的语句 如果驱动程序无法成功准备当前查询。

    模拟模式就像您描述的那样:PHP 有一个 SQL 解析器,可以用实际值替换占位符。唯一实际的好处是代码更干净,更易于维护。

    Native 模式基本上通过两个独立的通道将代码和数据发送到服务器。数据可以按原样发送(即使在二进制模式下)。这需要客户端和server 的支持。好处包括安全性、节省带宽以及一次解析 SQL 代码并使用不同的数据集运行多次的可能性。实际实现取决于 DBMS。

    【讨论】:

    • 所以数据和查询是分开的,因为它们使用两个不同的通信渠道?
    • 不要太从字面上理解“频道”这个词。我的意思是——在原生准备好的语句中——代码和数据不会被塞进一个字符串中。我还没有研究过任何 DBMS 使用的通信协议的细节。
    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 2010-11-30
    • 1970-01-01
    • 2011-07-13
    • 2017-09-29
    • 2014-07-20
    相关资源
    最近更新 更多