Mysql 与PDO::quote相比,预处理语句的安全优势

Mysql 与PDO::quote相比,预处理语句的安全优势,mysql,pdo,prepared-statement,Mysql,Pdo,Prepared Statement,在一次性查询中,预处理语句是否比PDO::quote提供了任何安全优势 例如,如果我有以下只执行一次的查询,那么与下面准备的等价查询相比,有什么缺点吗 // Using PDO::quote $stmt = $db->query("SELECT * FROM `config` WHERE name = {$db->quote($name)} LIMIT 1"); // Using prepared statement $stmt = $db->prepare("SELECT

在一次性查询中,预处理语句是否比
PDO::quote
提供了任何安全优势

例如,如果我有以下只执行一次的查询,那么与下面准备的等价查询相比,有什么缺点吗

// Using PDO::quote
$stmt = $db->query("SELECT * FROM `config` WHERE name = {$db->quote($name)} LIMIT 1");

// Using prepared statement
$stmt = $db->prepare("SELECT * FROM `config` WHERE name = :name LIMIT 1");
$stmt->execute(['name' => $name]);
我已经读到,由于两步执行,准备好的语句稍微慢一点。初始准备步骤是在数据库服务器上执行的,还是由PDO扩展处理的?

取自:

如果使用此函数生成SQL语句,强烈建议您使用PDO::prepare()来准备带有绑定参数的SQL语句,而不是使用PDO::quote()将用户输入插入SQL语句。带有绑定参数的预处理语句不仅更易于移植、更方便、不受SQL注入的影响,而且通常比插值查询执行得更快,因为服务器端和客户端都可以缓存已编译的查询形式

在一次性查询中,prepared语句是否比PDO::quote提供了任何安全优势

是:它适用于数值参数和字符串
PDO::quote()
仅适用于字符串和日期

我已经读到,由于两步执行,准备好的语句稍微慢一点

如果是,除非您的网络非常缓慢或需要修复,否则差异是微不足道的。不要担心,除非你在一个非常非常高的范围内操作(提示:你不能在那个范围内操作)

初始准备步骤是在数据库服务器上执行的,还是由PDO扩展处理的

或者,取决于
PDO::ATTR\u EMULATE\u属性。如果将其设置为true,则
prepare()
为no op(将SQL字符串保存在变量中除外),稍后当您
execute()
时,它会将参数插入SQL字符串,并在不准备的情况下执行查询


如果
PDO::ATTR\u EMULATE\u PREPARES
为false,它将执行服务器端准备。DBMS在内存中保存一些对象来表示查询,只有在执行调用中单独发送参数值时,DBMS才能执行准备好的查询。

“PDO::quote()仅适用于字符串和日期。”假设您按照手册中的说明正确设置了默认字符集,那么它是“安全的”。。“我已经读到,由于两步执行,prepared语句稍微慢一些。”此外,当您使用
PDO::quote()
时,您还使用两步执行。。“或者,取决于PDO::ATTR\u EMULATE\u PREPARES属性。如果将其设置为true,则prepare()是不可操作的”,此外,在
ATTR\u EMULATE\u PREPARES
模式中使用PDO与使用
PDO::qoute()
mysqli\u real\u escape\u string()一样不安全
因此,我建议任何人都不要使用这种模式,即使这种模式更快。如果开发人员坚持使用引号或转义字符串,那么使用引号或转义字符串是安全的,100%的时间都是安全的。但这是一个大问题,开发人员编写的应用程序代码不一定经过良好测试,以确保它们一致地避开参数。使用模拟prepare的优点是,它使开发人员更容易使用经过良好测试的代码进行转义。但是,是的,我同意通常使用适当的服务器端准备会更好。尽管有时如果应用程序开发人员没有适当地释放准备好的语句,服务器端准备可能是一种负担。根据准备好的语句的累积,它可能导致DBMS服务器中的资源泄漏。是的。如果关闭会话,则与该会话关联的所有资源都将被清理。如果您使用传统的PHP或任何其他基于旧式CGI类型体系结构的“无共享”语言,就会自然而然地发生这种情况。但是,如果您有一个长期会话,则准备好的语句句柄可能会在服务器中累积。
PDO::quote()
顺便说一下,还需要两步执行。@RaymondNijland,IIRC,quote()是客户端代码,因此不会产生网络往返。这正是那些预先准备好的声明的批评者经常担心的。@RaymondNijland
mysql\u real\u escape\u string
不需要往返数据库服务器。