0

我有这个 PDO 包装器

private function cleanup($bind) {
    if(!is_array($bind)) {
        if(!empty($bind))
            $bind = array($bind);
        else
            $bind = array();
    }
    return $bind;
}

public function run($sql, $bind="") {
    $this->sql = trim($sql);
    $this->bind = $this->cleanup($bind);
    $this->error = "";
    array_push($this->qs, $sql);

    try {
        $pdostmt = $this->prepare($this->sql);
        if($pdostmt->execute($this->bind) !== false) {
            if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql))
                return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
            elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql))
                return $pdostmt->rowCount();
        }
    } catch (PDOException $e) {
        $this->error = $e->getMessage();
        $this->debug();
        return false;
    }
}

自从几年前我开始使用它以来,我对此没有任何问题,现在我收到一条错误消息,因为没有转义字符串。也许我从来没有处理过这样的场景。

这是导致问题的 SQL 语句

$db->run("SELECT region_id FROM region WHERE name = '$name'");

$name霍克斯湾在哪里。我的印象是 PDO 转义字符串,好像我错了。有什么想法可以解决这个问题吗?

4

2 回答 2

3

有 2 个错误的假设导致您提出这个问题

  1. 转义是使您的查询正确的事情。
  2. PDO 会以任何“魔法”方式“逃避”,以某种方式知道要逃避什么。

不幸的是,这两个假设都是错误的。

事实上,只有 SQL 字符串需要转义。它与 PDO、准备好的陈述、安全等无关。一旦您要将字符串文字放入查询中 - 它必须有特殊字符转义。
但是一旦你不是 - 没有逃避是好的。

关于 PDO,您不希望它“转义”,而是在查询中处理占位符。这就是整个事情的运作方式。使用占位符告诉 PDO正确格式化相应的值。虽然这种格式不仅涉及转义,还涉及更多不同的措施。

所以,它必须是这样的

$db->run("SELECT region_id FROM region WHERE name = :name", array(':name' => $name));

这样 PDO 会将 $name 视为字符串并相应地对其进行格式化。

虽然我不确定“清理”功能是否正常工作以及为什么要使用它。

于 2013-08-03T12:49:35.667 回答
0

默认情况下,如果您使用普通查询而不是准备好的语句,则 PDO 不会引用任何内容。但是您可以使用PDO::quote()方法来转义单个值。查看更多http://www.php.net/manual/en/pdo.quote.php

于 2013-08-03T12:54:19.247 回答