PDO bindParam表现得很奇怪

时间:2011-02-11 20:14:13

标签: php pdo

我在让PDO bindParam正常工作时遇到问题。使用此代码:

$foo = "bar";

$stmt_1 = $db->prepare("SELECT * FROM table WHERE foo = $foo");
$stmt_1->execute();
$results_1 = $stmt_1->fetchAll();

$stmt_2 = $db->prepare("SELECT * FROM table WHERE foo = ?");
$stmt_2->bindParam(1, $foo, PDO::PARAM_STR);
$stmt_2->execute();
$results_2 = $stmt_2->fetchAll();

$stmt_3 = $db->prepare("SELECT * FROM table WHERE foo = :foo");
$stmt_3->bindParam(":foo", $foo, PDO::PARAM_STR);
$stmt_3->execute();
$results_3 = $stmt_3->fetchAll();

$ results_1只包含foo = bar的行,$ results_2为空,$ results_3包含“table”中的每个条目

bindValue也有完全相同的问题。任何人都知道这里发生了什么或我做错了什么?

3 个答案:

答案 0 :(得分:1)

(我会做一个新答案,因为我误解了另一个问题。)

默认情况下,PDO会静默忽略错误并返回空结果。这可以解释#2。例如,如果你的表真的被称为“表”而你没有用反引号引用它(table是一个保留的关键字)。打开错误报告以查看是否是这种情况(见下文)。

在#3中,可能会返回所有行,因为条件是重复的:foo = foo:foo = :foo'foo' = :foo

这是一个适合我的完整程序。如果它对您不起作用,则可能是特定版本的PHP,PDO或MySQL中的错误。

<?php

$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$foo = 'bar';

$stmt_1 = $db->prepare("SELECT * FROM `table` WHERE foo = '$foo'");
$stmt_1->execute();
$results_1 = $stmt_1->fetchAll();

$stmt_2 = $db->prepare("SELECT * FROM `table` WHERE foo = ?");
$stmt_2->bindParam(1, $foo, PDO::PARAM_STR);
$stmt_2->execute();
$results_2 = $stmt_2->fetchAll();

$stmt_3 = $db->prepare("SELECT * FROM `table` WHERE foo = :foo");
$stmt_3->bindParam("foo", $foo, PDO::PARAM_STR);
$stmt_3->execute();
$results_3 = $stmt_3->fetchAll();

print_r($results_1);
print_r($results_2);
print_r($results_3);

答案 1 :(得分:1)

我解决了我的问题。由于某种原因,我从$ _POST设置的变量不可用于我定义的类的内部函数,所以我在类中添加了一个参数数组来保存绑定变量,现在一切正常。

答案 2 :(得分:0)

参数foo = ?

"bar"相当于foo = 'bar',而不是foo = bar
即,您选择的是列等于字符串的位置,而不是另一列。

此处无需使用参数,因为$foo不是用户输入。 (如果是,则应根据表中的有限列进行验证。)


基本上,执行SQL查询有两个阶段:解析和评估。只有在将解析器公开给用户输入时,才会发生SQL注入。无论列中的值如何,评估都是安全的。

因此,当您运行WHERE foo = bar;时,它会被解析为“比较列foobar”。这是数据库唯一能做的事情,无论这些列中 的值是什么。