2010-09-16 40 views
8

请仔细阅读问题。这不是平常愚蠢的“我的代码不起作用!!!”题。PDO参数化查询的工作方式

当我运行此代码预期错误

try { 
    $sth = $dbh->prepare("SELECT id FROM users WHERE name INN(?,?) "); 
    $sth->execute(array("I'm","d'Artagnan")); 
} catch (PDOException $e) { 
    echo $e->getMessage(); 
} 

我收到此错误信息

你在你的SQL语法...近 'INN(' 有一个错误I \ 'm','d'Artagnan')'在第1行

但我想多年来,查询和数据被单独发送到服务器,干扰。因此,我有一些问题(虽然我怀疑有人得到答案...)

  1. 它在哪里得到这样一个熟悉的字符串表示 - 引用和转义?是否特别报告错误或是否是实际查询的一部分?
  2. 它是如何工作的?它是否用数据替换占位符?
  3. 有没有办法让整个查询,而不是一点点,用于调试目的?

更新

mysqli做它如期望的那样,它抛出一个错误说:near 'INN(?,?)'

+0

@DrColossos有答案,@Cassy有解释。 – 2010-09-16 13:45:28

回答

7

尝试添加

$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

;)

+0

宾果!我正要写另一个更新,正是关于这个主题,指向这个手册页上的第二段http://php.net/manual/en/ref.pdo-mysql.php,并询问是否有方法来测试是什么模式。刚刚测试过你的代码,它工作。错误消息 – 2010-09-16 15:34:09

+0

中没有转义字符串,您实际上也解决了我的其他问题:) – 2010-09-16 15:42:40

7

我不知道所有的细节,但我会尽量回答。

  1. 引用发生在数据库端。数据库转义并清理它接收到的所有值(参见第2项),以便正确解释它。 错误发生的那一刻,数据库(在本例中为MySQL)输出它试图运行的查询。如果它只显示准备好的部分,这不会有帮助。不,它不。准备工作时,查询将在服务器端进行编译。当使用值执行查询时,仅传输值。这与直接在数据库上调用PREPARE和EXECUTE几乎相同。

  2. 这取决于您使用的数据库。例如,MySQL可以将所有查询记录到日志文件(检查my.cnf设置)。但是你也可以在PHP端使用debugDumpParams()

我希望这有点帮助。

+0

感谢您的明智回应。我不能将1和2绑在一起。这是否意味着最后它引用/转义是相同的,但只是在服务器端进行? – 2010-09-16 13:47:41

+1

+1用于回答实际问题并且不专注于IN/INN事物。因为第一句解释语法错误是*故意* – Jake 2010-09-16 13:48:18

+0

@Col。弹片:对于数据库1和2是两个不同的命令。第一个“注册”查询(如果你愿意的话,可以将其作为一个函数),第二个参数传递给它。在这种方法中,数据库完全知道它可以/必须/应该引用哪个部分的查询。它不能在组合查询上做到这一点。 – 2010-09-16 13:52:31