Как правильно построить SQL-запрос в PHP-скрипте?

Я пытаюсь создать SQL-запрос для вставки информации о пользователе в базу данных. Переменные $fname и $lname содержат правильные значения («John» и «Doe»), но запрос завершается с ошибкой. Вот мой код:

 $fname = $_POST['first_name']; $lname = $_POST['last_name']; $sql = "INSERT INTO users (fname, lname) VALUES ($fname, $lname)"; mysqli_query($conn, $sql); 

после проверки сообщения об ошибке я обнаружил, что этот запрос завершился с ошибкой.

Неизвестный столбец «Джон» в списке полей

Как правильно включить переменные в SQL-запрос, чтобы он запускался без ошибок?

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

Самый ошибочный способ добавить переменную в SQL-запрос – добавить ее через подготовленный оператор .

Очень важно понять, что просто добавлять кавычки вокруг переменной недостаточно и в конечном итоге приведет к бесчисленным проблемам, от синтаксических ошибок до SQL-инъекций. С другой стороны, из-за самой природы подготовленных заявлений это пуленепробиваемое решение, которое делает невозможным введение какой-либо проблемы через переменную данных.

Таким образом, для каждого выполняемого вами запроса, если будет использоваться хотя бы одна переменная, вы должны заменить ее заполнителем, затем подготовить свой запрос, а затем выполнить его, передав переменные отдельно.

Прежде всего, вы должны изменить свой запрос, добавив вместо переменных переменные. Ваш запрос станет следующим:

 $sql = "INSERT INTO users (fname, lname) VALUES (?, ?)"; 

Затем вам придется подготовить его, привязать переменные и выполнить:

 $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "ss", $fname, $lname); mysqli_stmt_execute($stmt); 

Как вы можете видеть, это всего лишь три простых команды:

  • prepare (), где вы отправляете запрос с заполнителями
  • bind_param, где вы отправляете строку с типами («s» для строки, и вы можете использовать ее для любого типа на самом деле), а не фактические переменные.
  • и выполнить ()

Таким образом, вы всегда можете быть уверены, что ни одна синтаксическая ошибка SQL не может быть вызвана данными, добавленными в запрос! В качестве бонуса этот код также защищен от броузеров от SQL-инъекции!

Однако есть щепотка соли, поскольку выполнение запроса SELECT с подготовленными операциями mysqli может быть более сложным. Поэтому я настоятельно рекомендую выбрать PDO в качестве драйвера базы данных по многим причинам .