0

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

$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();
}
4

2 回答 2

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()而不是单独绑定它们): http: //php.net/manual/en /pdo.prepare.php

于 2013-06-27T22:42:33.723 回答
1

您肯定需要保护它们 - 否则,有人可能会输入“AMADANON 的标题”标题 - 撇号会将数据库视为关闭引号。这是一个无意的例子,也会有人试图攻击你的数据库。

推荐的(1)方法是使用参数。使用VALUES(?,?,?),然后在调用执行时,将变量传递到那里。

有关更多信息,请阅读 PHP 手册,查看示例

我不喜欢绑定变量,很难看到在哪里发生了什么。

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

转义是可以接受的,但我看不出它在哪里增加了任何好处,并且参数更清晰。

(1) 由我

于 2013-06-27T22:46:29.817 回答