我在PHP中运行此代码时收到错误

时间:2013-09-10 20:15:44

标签: php mysql pdo

我一直收到此错误消息的一些变体:

  

警告:PDO :: exec():SQLSTATE [42000]:语法错误或访问   违规:1064您的SQL语法有错误;检查手册   对应于您的MySQL服务器版本,以获得正确的语法   在'@ email.com“附近使用,5,2)'在第1行   第31行的C:\ xampp \ htdocs \ donations \ index.php

它所指的PHP是:

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

我没有正确逃避或者我的报价太多了吗?任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:4)

您已经使用PDO走上了正确的轨道。现在,下一步是使用prepared statements正确使用它。

据说你的代码看起来像这样:

//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;

进一步阅读:

答案 1 :(得分: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更具可读性。

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

$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()。他们也更倾向于使用?占位符而不是命名占位符,但对我来说,这只是懒惰。我的意思是你真的节省了那么多时间来写一些额外的字符来牺牲代码的清晰度吗?

答案 2 :(得分:0)

在字段/表名和parantheses之间添加空格

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

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

VALUES('“。$ _POST ['name']。”')

此外,永远不要将$ POST数据直接注入到SQL查询中。这是求助于SQL注入。并且无论如何,去学习PDO / Prepared Statements并停止使用mysql 功能。它死了。