1

I keep receiving some variant of this error message:

Warning: PDO::exec(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@email.com",5,2)' at line 1 in C:\xampp\htdocs\donations\index.php on line 31

The PHP it is referring to is this:

$db->exec("INSERT INTO donations(name, email, donation_amount, item_id) VALUES(\"" . $_POST['name'] . "\"," . $_POST['email'] . "\"," . $_POST['amount'] . "," . $_POST['radioButtons'] . ");");

Am I not escaping correctly or do I have too many quotes? Any help is appreciated!

4

3 回答 3

4

您已经在使用 PDO 的正确轨道上。现在下一步是通过使用准备好的语句来正确使用它。

话虽如此,您的代码可能看起来像这样:

//TODO Check, validate, sanitize your input...
$name = $_POST['name'];
$email = $_POST['email'];
$donation_amount = $_POST['amount'];
$item_id = $_POST['radioButtons'];

try {
    $db = new PDO('mysql:host=localhost;dbname=your_db_name', 'user', 'password');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    //Construct your query with placeholders
    $sql = "INSERT INTO donations (name, email, donation_amount, item_id) 
            VALUES (?, ?, ?, ?, ?)";
    //Prepare your query
    $query = $db->prepare($sql);

    //Execute it passing parameters
    $query->execute(array($name, $email, $donation_amount, $item_id));

} catch (PDOException $e) {
    echo "Exception: " . $e->getMessage(); //TODO better error handling
}
$query = null;
$db = null;

进一步阅读:

于 2013-09-10T20:22:27.480 回答
1

您的问题实际上是转义引号的问题。如果您在 SQL 语句中使用更标准的单引号将值括起来,您可能会更容易注意到这一点,但您目前在电子邮件值之前没有开引号。

我强烈建议使用这样的准备好的语句:

$query = 'INSERT INTO donations (name, email, donation_amount, item_id) VALUES (:name, :email, :amount, :radioButtons)';
$sth = $db->prepare($query);
$sth->execute(array(
    ':name' => $_POST['name'],
    ':email' => $_POST['email'],
    ':amount' => $_POST['amount'],
    ':radioButtons' => $_POST['radioButtons']
));

当然,这不应该进行正确的错误处理,您也希望在此过程中进行适当的处​​理。

这个准备好的语句将保护您免受 SQL 注入,并且还具有通过消除对引号的需要使您的 SQL 更具可读性的好处。

我实际上更喜欢使用更详细的方法来绑定所有参数,而不是传递一个值数组来执行。这允许您明确指定输入类型(即整数、字符串等)。因此,基于最后两个值是整数的假设可能如下所示:

$query = 'INSERT INTO donations (name, email, donation_amount, item_id) VALUES (:name, :email, :amount, :radioButtons)';
$sth = $db->prepare($query);
$sth->bindParam(':name', $_POST['name'], PDO::PARAM_STR);
$sth->bindParam(':email', $_POST['email'], PDO::PARAM_STR);
$sth->bindParam(':amount', $_POST['amount'], PDO::PARAM_INT);
$sth->bindParam(':radioButtons', $_POST['radioButtons'], PDO::PARAM_INT);
$sth->execute();

我最初并没有这样写,因为我认为,无论出于何种原因,PHP 社区在很大程度上倾向于通过数组将值传递给execute(). 他们也更倾向于使用?占位符而不是命名占位符,但是,对我来说,这只是懒惰。我的意思是你真的节省了那么多时间来写一些额外的字符来牺牲代码的清晰度吗?

于 2013-09-10T20:29:52.597 回答
0

在字段/表名称和括号之间添加空格

INSERT INTO donations (name...) VALUES (...)

此外,在值周围使用单引号 ' '。

值('".$_POST['name']."')

此外,切勿将 $ POST 数据直接注入您的 SQL 查询中。这是在乞求 SQL 注入。无论如何,去学习 PDO/Prepared Statements 并停止使用 mysql功能。它死了。

于 2013-09-10T20:17:57.477 回答