什么时候应该准确使用准备好的陈述

时间:2016-06-03 23:10:12

标签: php mysql security pdo parameter-passing

我想知道,我可以只使用一次准备好的陈述吗?

这是我的剧本:

$stm = $db->prepare("UPDATE
                     qanda AS ans1
                     JOIN qanda AS ans2 ON ans2.related = ans1.related
                     JOIN qanda AS ques ON ans2.related = ques.id
                     SET ans1.acceptedanswer = 1,
                         ans1.aadate = IF( ans1.id <> ?, ans1.aadate, ?)
                     WHERE ques.author_id = ? AND ans2.author_id = ? 
                                        ");
$stm->execute(array($answer_id, time(), $_SESSION["Id"], $author_id));
$done = $stm->rowCount();

if ($done){
    /* I don't use prepared statement here */
    $stm1 = $db->prepare("UPDATE user SET rep = rep + 15 WHERE id = $author_id");
    $stm1->execute();
}

如您所见,我没有使用预备语句进行第二次查询。因为我是为第一次查询而做的,如果第一个查询正在运行,那么我确定参数是有效的,不需要通过预处理语句绑定它们。

请不要问我为什么你不想使用准备好的状态进行第二次查询,因为原因太长了。

那我正在做的是对的吗?是不是有任何安全问题?

1 个答案:

答案 0 :(得分:3)

直接的答案是:是的,你可以。

原因实际上取决于您,因为无论如何,只要您传递值,就可以使用预准备语句。

另外考虑一下,如果你没有绑定任何参数,使用query()方法更有意义,只是为了明确你不会绑定任何东西。所以你的第二个查询将是

$stm1 = $db->query("UPDATE user SET rep = rep + 15 WHERE id = $author_id");

参见http://php.net/manual/en/pdo.query.php

而不是

$stm1 = $db->prepare("UPDATE user SET rep = rep + 15 WHERE id = $author_id");
$stm1->execute();

此外,您提到了动态查询,但这不是您的示例代码的情况。无论如何,我将举例说明两个如何使用预准备语句对动态生成的查询。

这是一个愚蠢的例子,但应该足以让你有个想法。

假设我们有一些值可以更新&#39; email&#39;,&#39; date_of_birth&#39;和&#39;网站&#39;。我们想说在插入数据之前我们要对这些数据进行一些检查。我假装我们已经有了一个有效的()函数。

    $dynamic_sql = array();
    $parameters[':date_of_bird'] = $date_of_birth;

    if(valid($email)) {
        $dynamic_sql['email_sql'] = "email = :email";
        $parameters[':email'] = $email;

    }
    if(valid($website)) {
        $dynamic_sql['website_sql'] = "website = :website";
        $parameters[':website'] = $website;
    }

    if(count($dynamic_sql)>0) {
        $dynamic_sql = ','.implode($dynamic_sql);
    }

    $query = "UPDATE user
    SET date_of_birth = :date_of_birth $dynamic_sql
    WHERE
    user_id = :user_id";

    $stm = $db->prepare($query);
    $stm->execute($parameters);

这种方法允许您继续使用预处理语句和动态生成的SQL。