[英]Why do I get an Intermittent syntax error on this php code?
执行下面的 PHP 代码时,我间歇性地收到此错误。 该查询每次都在 PHPMyAdmin 中工作。 我曾尝试更改引号并将 spotId 更改为不同类型的变量,但似乎没有任何解决方法。
错误:
错误描述:你的SQL语法有错误; 检查与您的 MariaDB 服务器版本相对应的手册,了解在“INSERT INTO 点(`userId`、`desc`、`lat`、`lng`、`type`)附近使用的正确语法(第 2 行的“3wBVC92S7VTGBOdg”)
PHP代码:
<?php
include 'connect.php';
$userId = $_POST['userId'];
$desc = $_POST['desc'];
$lat = (float) $_POST['lat'];
$lng = (float) $_POST['lng'];
$type = $_POST['type'];
$difficulty = (int) $_POST['difficulty'];
$hostility = (int) $_POST['hostility'];
$spotId = null;
// upload spot
$sql = "BEGIN;
INSERT INTO spots (`userId`,`desc`,`lat`,`lng`,`type`) VALUES ('$userId','$desc','$lat','$lng','$type');
SET $spotId = LAST_INSERT_ID();
INSERT INTO diffrating (`rating`) VALUES ('$difficulty');
INSERT INTO userdiffrating (`ratingId`,`userId`,`spotId`) VALUES (LAST_INSERT_ID(),'$userId','$spotId');
INSERT INTO hostrating (`rating`) VALUES ('$hostility');
INSERT INTO userhostrating (`ratingId`,`userId`,`spotId`) VALUES (LAST_INSERT_ID(),'$userId','$spotId');
COMMIT;";
//echo $sql;
if(mysqli_query($con,$sql)){
echo("Spot uploaded successfully.");
}
else{
echo 'Try Again';
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
echo $spotId;
echo("Error description: " . mysqli_error($con));
exit;
}
?>
要使用mysqli
执行此操作,您需要对其进行调整以使用占位符值。 这并不难:
$con->begin_transaction(); // Equivalent to BEGIN;
$spots_stmt = $con->prepare('INSERT INTO spots (`userId`,`desc`,`lat`,`lng`,`type`) VALUES (?,?,?,?,?)');
$spots_stmt->bind_param('isdds', $userId, $desc, $lat, $lng, $type);
$spots_stmt->execute();
$spotId = $spots_stmt->insert_id; // Grabs LAST_INSERT_ID()
$rating_stmt = $con->prepare('INSERT INTO userdiffrating (`ratingId`,`userId`,`spotId`) VALUES (?,?,?)');
$rating_stmt->bind_param('iii', $ratingId, $userId, $spotId);
$rating_stmt->execute();
// ...
$con->commit();
如果您使用带有占位符值的准备好的语句,那么转义问题就会完全消失。 您必须专注于确保正确绑定值,但仅此而已。
第一次和每次都应该编写这样的查询,这样您创建的错误就不会再发生了。 这不仅仅是安全问题,这是关于尊重您的时间。 您浪费在追查这些错误上的每一秒都是完全可以避免的。
我故意在这里做的一件事是使用单引号。 这会禁用通常的字符串插值,所以如果你因为旧习惯重铺而做类似'INSERT ... VALUES ("$x")'
的事情,那么发生的最糟糕的事情就是你在那个领域得到了字面上的$x
,你没有有一个注入错误。 这个错误真的很容易发现,因为它永远不会正常工作,但它基本上是无害的并且很容易修复。 注入错误可能会被忽视,然后会导致灾难性的问题。
还值得注意的是,如果您对mysqli
不太投入,那么您可能想考虑 PDO。 它支持命名占位符、除 MYSQL 以外的数据库,并且使用起来更加愉快。
命名占位符意味着您可以针对关联数组准备和执行,没有绑定步骤。 作为一个加号,弄乱插入的顺序或无意中使用错误的类型要困难得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.