准备好的语句,转义变量

时间:2013-06-27 22:38:53

标签: pdo

我是否需要做任何事情来保护这三个变量,比如使用转义字符串或绑定它们?我不确定我是否正确地做了这个,人们只是建议使用准备好的语句,所以我试图弄清楚它们。

$order = $_POST['order'];
$heading = $_POST['heading'];
$content = $_POST['content'];    
try {
$dbh = new PDO("mysql:host=$hostname;dbname=saintfiv_faq", $username, $password);
/*** echo a message saying we have connected ***/
echo 'Connected to database<br />';

/*** INSERT data ***/
$stmt = $dbh->prepare("INSERT INTO faq(`order`, `heading`, `content`) VALUES (:order, :heading, :content)");
$stmt->bindParam(':order', $order, PDO::PARAM_INT);
$stmt->bindParam(':heading', $heading, PDO::PARAM_STR, strlen($heading));
$stmt->bindParam(':content', $content, PDO::PARAM_STR, strlen($content));
/*** close the database connection ***/
$stmt->execute();
}
catch(PDOException $e)
{
echo $e->getMessage();
}

2 个答案:

答案 0 :(得分:2)

您没有在代码中使用预准备语句。准备好的陈述看起来更像是这样:

$stmt = $db->prepare("INSERT INTO foo (bar, baz) VALUES (?, ?);");

$stmt->bindValue(1, "Fez");
$stmt->bindValue(2, "Hat");
$stmt->execute();

您的示例代码可能容易受到SQL注入攻击,因为您只是将变量直接插入SQL字符串中。您将要使用预准备语句并绑定值(这是首选解决方案),或者只是确保您正确地转义exec()的所有输入。

值得一提的是exec()适用于完全硬编码的语句 - 例如$db->exec("SELECT foo FROM bar;"); - 因为SQL是硬编码的,所以没有SQL注入的可能性。但是,我喜欢总是使用prepare来代替风格。

要在代码中专门执行查询,您可以执行以下操作:

$stmt = $db->prepare("INSERT INTO faq (`order`, `heading`, `content`) " .
    "VALUES (?, ?, ?);");

$stmt->bindValue(1, $order);
$stmt->bindValue(2, $heading);
$stmt->bindValue(3, $content);
$stmt->execute();

我还推荐正式的PHP文档,因为它显示了做同样事情的其他一些方法(即,您可以将参数作为数组传递给execute()而不是单独绑定它们:{{3 }}

答案 1 :(得分:1)

你肯定需要保护它们 - 否则,有人可能会在“AMADANON's Heading”标题中加入 - 而撇号则会将数据库视为近距离引用。这是一个不可忽视的例子,也有人试图攻击你的数据库。

建议的(1)方法是使用参数。使用VALUES(?,?,?),然后在调用execute时,传递变量。

有关详细信息,请Read the PHP manual, check out the examples

我不喜欢绑定变量,很难看出会发生什么。

这也意味着您可以准备一次游标(带有SQL语句),然后使用不同的参数多次使用它。

逃避是可以接受的,但我没有看到它增加任何好处,参数更清晰。

(1)由我