php - 为什么要使用 ATTR_EMULATE_PREPARES,mysql_real_escape_string 有什么替代品吗?在 PDO 中

标签 php mysql pdo prepared-statement sql-injection

<分区>

  1. 在 PDO 中是​​否有任何替代方案,如在 mysql 中是 mysql_real_escape_string?
  2. 为什么我们应该设置 'false' -> ATTR_EMULATE_PREPARES 常量?

最佳答案

使用 mysql 扩展,将值动态嵌入查询的唯一方法是:

$query = "SELECT ... WHERE foo = '$bar'";

为了避免在最坏的情况下可能被利用为 SQL 注入(inject)的语法错误,您需要将 mysql_real_escape_string 应用于此处的 $bar转义 正确的值。阅读The Great Escapism (Or: What You Need To Know To Work With Text Within Text)如果您不知道这意味着什么。

准备好的语句通过完全分离查询和值提供了一种完全不同的方式来使用动态值:

$stmt = $db->prepare('SELECT ... WHERE foo = :bar');
$stmt->execute(array(':bar' => $bar));

这实际上是作为两个单独的部分发送到数据库的;语法永远不会被搞乱或被利用,因为这两个部分从来没有真正合并过。

尽管并非所有数据库都支持此功能,但一些(较旧的)数据库仍然需要旧式的、未准备好的转义查询。 ATTR_EMULATE_PREPARES 提供了模拟 准备语句的选项。您仍然可以在代码中使用 $db->prepare()->execute() API,但在后台 PDO 将转义该值并将其连接到查询中。要明确禁止 PDO 这样做并强制它使用数据库提供的 native 准备语句 API,请将 ATTR_EMULATE_PREPARES 设置为 false

如果你的数据库本身就支持预处理语句,你应该这样做;所有中途最近的数据库都这样做。如果您让 PDO 模拟准备好的语句,在某些条件下(主要是在人工构造的多字节连接编码情况下 AFAIK),SQL 注入(inject)的机会仍然很小。

在任何情况下,您都不会将 mysql 扩展中的函数与 PDO 扩展一起使用;它一开始是行不通的,因为 mysql_real_escape_string 需要通过 mysql_connect 建立一个单独的数据库连接。

关于php - 为什么要使用 ATTR_EMULATE_PREPARES,mysql_real_escape_string 有什么替代品吗?在 PDO 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17059362/

相关文章:

PHP 的 error_log() 与 syslog()

php - 在 wordpress 中更改小部件内的默认 HTML 标记

php - 非常简单的联盟计划

php阻止来自mysql数据库的单词

php - 由于找不到 pdo_mysql 驱动程序导致 Yiic 迁移错误

php - 删除 Drupal CSS

Mac OS 的 Mysql-dev

mysql - 无法再在 DirectAdmin 中启动 MySQL

php - 使用 PHP PDO 运行 "show slave status"

php - PDO: 找不到驱动程序 php/mysql