Я приведу небольшой пример, не использующий SQL. Представьте, что у вас есть этот код PHP:
<?php
echo 'Hello, world!';
Теперь вы хотите заменить world
на O'Hara
:
<?php
echo 'Hello, O'Hara!'; // Parse error: syntax error, unexpected T_STRING, expecting ',' or ';'
Да, конечно, это не правильный PHP. Вы должны избегать одиночной кавычки, поскольку она интерпретируется как буквальная кавычка, а не как разделитель строк:
<?php
echo 'Hello, O\'Hara!';
У вас точно такая же проблема при составлении SQL-запросов. Если вы введете случайный ввод в свой код, рано или поздно он сломается. Вам необходимо кодировать ввод, чтобы он обрабатывался как буквенный ввод, а не как поврежденный код.
Как ты можешь это сделать? Ну, MySQL принимает \'
точно так же, как PHP (хотя это только совпадение: другие движки баз данных используют другие методы escape). Таким образом, самое глупое решение - добавить обратную косую черту здесь и здесь:
SELECT id FROM user WHERE name='O\'Hara';
Конечно, очень сложно жестко закодировать все возможные символы, которые нужно экранировать (и вы, вероятно, забудете некоторые из них), так что вы можете использовать функцию, которая сделает эту работу за вас: либо mysql_real_escape_string()
или mysqli_real_escape_string()
.
Вопрос: это достаточно хорошо? Ну, это вроде работает, но это приводит к раздражающему коду, который сложно поддерживать:
$sql = "UPDATE user SET name='" . mysql_real_escape_string($name) . "' WHERE id='" . mysql_real_escape_string($id) . "'";
... и вам все равно нужно позаботиться об окружении полного значения одинарными кавычками ... которые не всегда обязательны (подумайте о числах) ... Какой беспорядок. Не может ли кто-то изобрести что-то лучше? Хорошие новости: они сделали! Это называется подготовленные заявления :
// Just an example, I invented the syntax
$sql = 'UPDATE user SET name=:name WHERE id=:id';
$params = array(
'name' => "O'Brian",
'id' => 31416,
);
$MyDbConnection->execute($sql, $params);
В реальной жизни:
- MySQLi имеет метод
prepare()
для этого. Найдите там несколько примеров .
- Устаревшее расширение MySQL ... не имеет ничего: оно вообще не поддерживает подготовленные операторы! Если вы используете это расширение, вы застряли с назойливыми методами add-quotes -self и string.
Надеюсь, это объясняет весь вопрос.