我从数据库中获取数据,并在另一个查询中重用它们.重新准备是多余的吗


I get data from db and reuse them in another query. Is it redundant to re-prepare them?

我一直想知道我的行为(总是准备/逃离)是多余的,还是出于安全原因,总是好做的

第一步-用户插入一些数据

例如,用户插入一个帖子。用户编写的这篇文章被保存到变量$post中。然后我把它放进数据库

 $stmt = $dbh->prepare("INSERT INTO posts VALUES (:post)"); //simplified query
 $stmt->bindParam(":post", $post); //i prevent SQL injection
 $stmt->execute(); //run the query

正如您所注意到的,我阻止了SQL注入。必要的,是用户写的$post。

第二步-我获取并在另一个查询中重用

出于某种原因,我拿到了后

$stmt = $dbh->prepare("SELECT post FROM posts WHERE ..."); //simplified query
$stmt->execute();
$post=$stmt->fetch(PDO::FETCH_COLUMN,0);

现在,和以前一样,我把帖子保存到$post中。不同的是,这篇文章是从DB而不是从用户那里获得的。

问题来了:如果我要在另一个查询(INSERT、compare、UPDATE等)中再次使用刚刚获取的$post,我应该再次准备/转义它吗?逻辑是肯定的,因为这个值在插入数据库时被转义了,但由于我不知道安全性,我想确定。。。也许通过不再逃跑,我给了一些黑客攻击我的应用程序的机会!

//are these dangerous?
$stmt = $dbh->prepare("SELECT something FROM somewhere WHERE some_value=$post");
$stmt = $dbh->prepare("INSERT INTO somewhere VALUES ($post)");
//are these safe or simply redundant?
$stmt = $dbh->prepare("SELECT something FROM somewhere WHERE some_value=:post");
$stmt->bindParam(":post", $post); //i prevent SQL injection
$stmt = $dbh->prepare("INSERT INTO somewhere VALUES (:post)");
$stmt->bindParam(":post", $post); //i prevent SQL injection

我相信prepared语句是查询参数的php版本。在这种情况下,安全并不是唯一的好处。

另一个好处是特殊角色可以逃脱。最常见的例子是撇号。你不希望撇号被当作单引号。坏事发生了。

另一个好处是性能更好,尤其是在繁忙的网站上。当你的数据库第一次看到一个sql字符串时,它必须编译它并制定一个执行计划。编译将缓存一段时间。如果使用不同的参数运行同一查询,它将使用缓存编译。如果你发送了一个不同的字符串,它将不得不重新编译。

即使数据来自数据库,使用查询参数也是一个好主意。