我在让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也有完全相同的问题。任何人都知道这里发生了什么或我做错了什么?
答案 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;
时,它会被解析为“比较列foo
和bar
”。这是数据库唯一能做的事情,无论这些列中 的值是什么。