【发布时间】:2016-09-04 13:10:05
【问题描述】:
根据经验,并且经常被告知使用准备好的语句和绑定我的参数的好处,我一直在我的代码中使用这两种技术,但是我想准确地了解这两种技术的用途:
根据我对准备好的语句的理解:
$sql = "SELECT * FROM myTable WHERE id = ".$id;
$stmt = $conn->prepare($sql);
$stmt->execute();
前面的代码应该使用我提出的查询在数据库中创建一种缓冲区。现在根据我的理解(我可能错了),前面的代码是不安全的,因为字符串 $sql 可以是任何东西,具体取决于 $id 的实际含义,如果 $id = 1; DROP TABLE myTable;--,即使我有准备好的语句,我也会插入恶意查询。
根据我的理解这是绑定我的参数的地方。如果我改为执行以下操作:
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
$stmt->execute();
数据库应该事先准确地知道 sql 语句的所有部分:
SELECT这些列:*FROM myTable和WHERE id =“用户输入的变量”,如果"a variable that was input by the user" != a variable,则查询失败。
有人告诉我我的理解是正确的,而其他人则告诉我这是错误的,如果我错了、正确或遗漏了什么,有人可以告诉我吗?并尽可能详细地说明,非常感谢所有反馈!
【问题讨论】:
-
第一段代码可以保护您一无所获,因为您仍在将
$id可能来自$_POST['id']直接传递到查询中 -
@RiggsFolly 所以我的假设是正确的,即准备好的语句需要
bindParam()才能保证安全? -
您必须使用
?,?或您的第二种机制 -
好吧,你也可以使用
$stmt->execute( [':id' => $id] );,但这基本上是不可见的绑定 -
也许您还缺少关于准备语句的一点是,如果您想在循环中加载数据,您可以
->prepare()一次和bind; execute()多次。因此只编译和优化一次查询,但使用它 100 次
标签: php mysql pdo prepare bindparam