Вопрос

Можете ли вы дать мне совет?Я искал вопросы, но не нашел ничего похожего на мой.

Как сделать так, чтобы вводимые пользователем данные автоматически экранировались, когда они предназначены для использования в запросах SQL?Мне не нравится, что мой код заполнен чем-то вроде

$var_x = $DB->Escape($_POST['var_x']);
$another_var = $DB->Escape($_POST['another_var']);
$some_string = $DB->Escape($_POST['some_string']);
...

Предполагая, что у меня есть класс базы данных с методом Escape, который выполняет mysql_real_escape_string

Но я также не могу установить автоматическое экранирование для SQL-запроса, поскольку оно нарушает запросы на вставку:

function Exec($sql){
   $result = mysql_query($this->Escape($sql));
}

$q = $DB->Exec("SELECT * FROM table WHERE id = 'xxx'");

Это делает их «ххх».что неверно.

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

Короче говоря, как сделать умное автоматическое экранирование, которое работает со всем запросом и экранирует только значения?

Это было полезно?

Решение

Фактически, единственное, что вам следует учитывать (очевидно, мы не говорим здесь о тестовых проектах), — это использование параметризованных операторов.Это единственный способ (конечно, когда SQL Synax позволяет это сделать).Если все сделано правильно, это не усложнит вашу систему, но воля сделать его более прочным.

Другие советы

Извините, вы ничего не можете автоматизировать.Когда вы объединяете строки, у вас всегда будут проблемы с экранированием символов;это не то, что можно «решить» один раз и больше никогда об этом не думать.

Если вы это сделаете:

$a= "a'b";
$query= "SELECT * FROM things WHERE name='$a'";

Тогда ваша строка запроса будет содержать как апострофы, которые являются настоящими апострофами в строковых литералах, так и апострофы, которые являются разделителями строк:

SELECT * FROM things WHERE name='a'b'

Нужно бежать;другой не должен.Как вы можете определить, что есть что?Нельзя, эта информация потеряна навсегда.Вместо этого вы должны сказать:

$query= "SELECT * FROM things WHERE name='".mysql_real_escape_string($a)."'";

(или любая другая escape-функция, которая больше подходит для используемой вами базы данных.)

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

Конкатенация строк выглядит просто.Люди думают, что понимают, как забиваются струны.Но на самом деле они этого не делают.

Я использую этот метод:

$db->set('name',$name);
$db->set('title',$title);
$db->insert('users');

Здесь $db->set() метод автоматически экранирует значение (т.е. второй аргумент).

С PHP 5 вы также можете сделать это:

$db->set('name',$name)->set('title',$title)->insert('users');

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

Хотите пояснить свое утверждение о том, что параметризованные запросы «более сложны»?Я не объединяю внешние данные в запросы – всегда - и это самая простая вещь в мире, к тому же она гораздо ближе к «пуленепробиваемому», чем любой другой метод побега.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top