Почему я получаю прерывистую синтаксическую ошибку в этом php коде? - PullRequest
1 голос
/ 04 февраля 2020

Я получаю эту ошибку периодически при выполнении кода PHP ниже. Запрос работает в PHPMyAdmin каждый раз. Я попытался изменить кавычки и изменить spotId на другой тип переменной, но, похоже, ничего не исправило.

Ошибка:

Описание ошибки: в вашем сообщении об ошибке SQL синтаксис; проверьте руководство, соответствующее вашей версии сервера MariaDB, на предмет правильного синтаксиса для использования рядом с точками INSERT INTO (`userId`,` desc`, `lat`,` lng`, `type`) VALUES ('3wBVC92S7VTGBOdg' в строке 2

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;

     }

    ?>

Структура базы данных: Database layout У кого-нибудь есть решение?

1 Ответ

4 голосов
/ 04 февраля 2020

Чтобы сделать это с 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();

Если вы использовали подготовленные операторы со значениями-заполнителями, то полностью избегаете проблем go. Вам нужно будет сосредоточиться на том, чтобы правильно связать значения, но это все.

Вы должны писать запросы, подобные , в первый раз и каждый раз , чтобы ошибки, подобные вы создали никогда не повторится Это не просто вопрос безопасности, речь идет об уважении вашего времени. Каждую секунду, которую вы тратите на погоню за этими ошибками, можно было полностью предотвратить.

Одна вещь, которую я специально сделал здесь, это использование одинарных кавычек . Это отключает обычную интерполяцию строк, так что если вы делаете что-то вроде 'INSERT ... VALUES ("$x")' из-за старых привычек, то самое худшее, что происходит, это то, что вы буквально получаете $x в этом поле, у вас нет ошибки внедрения. Эту ошибку действительно легко обнаружить, поскольку она никогда не будет работать правильно, но в основном она безвредна и легко устраняется. Ошибки впрыска могут быть пропущены и позже могут привести к катастрофическим проблемам c.

Стоит также отметить, что, если вы не слишком вкладываете средства в mysqli, вы можете вместо этого рассмотреть PDO. Он поддерживает именованные заполнители, базы данных, отличные от MYSQL, и удобнее в использовании.

Именованные заполнители означают, что вы можете подготовиться и выполнить с ассоциативным массивом, шаг привязки отсутствует. Кроме того, намного сложнее испортить порядок вставок или случайно использовать неправильный тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...