Подтвердить что ты не робот

Сброс логических карт MySQL

На более старом сервере я использую то, что я не могу использовать подготовленные инструкции. В настоящее время я пытаюсь полностью избежать ввода пользователя перед отправкой его в MySQL. Для этого я использую функцию PHP mysql_real_escape_string.

Так как эта функция не избегает подстановочных символов MySQL% и _, я использую addcslashes, чтобы избежать этих ошибок.

Когда я отправляю что-то вроде:

test_test " ' 

в базу данных, а затем прочитайте ее, как показывает база данных:

test\_test " ' 

Глядя на это, я не могу понять, почему у _ есть предыдущая обратная косая черта, а "и" - нет. Поскольку все они сбегаются с \surely _ 'и "все должно выглядеть одинаково, т.е. Все имеют видимый символ escape или все они не видны.

Выполняется ли экранирование автоматически для

Кто-нибудь может это объяснить?

4b9b3361

Ответ 1

_ и % не являются подстановочными знаками в MySQL в целом и не должны быть экранированы для того, чтобы помещать их в обычные строковые литералы. mysql_real_escape_string является правильным и достаточным для этой цели. addcslashes не следует использовать.

_ и % являются специальными только в контексте LIKE -matching. Если вы хотите подготовить строки для использования в буквальном использовании в инструкции LIKE, так что 100% соответствует стопроцентной, а не только любой строке, начинающейся со ста, у вас есть два уровня ускорения, о которых можно беспокоиться.

Первое - это LIKE экранирование. Обработка LIKE происходит полностью внутри SQL, и если вы хотите превратить литеральную строку в литеральное выражение LIKE, вы должны выполнить этот шаг, даже если вы используете параметризованные запросы!

В этой схеме _ и % являются специальными и должны быть экранированы. Эквивалентный символ также должен быть экранирован. Согласно ANSI SQL, символы, отличные от них, не должны быть экранированы: \' будет неправильным. (Хотя MySQL, как правило, позволяет вам уйти от него.)

Сделав это, вы перейдете ко второму уровню экранирования, который представляет собой простую старую строку литералов. Это происходит за пределами SQL, создавая SQL, поэтому это должно быть сделано после шага LIKE escaping. Для MySQL это mysql_real_escape_string по-прежнему; для других баз данных будет другая функция, вы можете просто использовать параметризованные запросы, чтобы избежать необходимости делать это.

Проблема, которая приводит к путанице здесь, заключается в том, что в MySQL используется обратная косая черта как escape-символ для обоих вложенных шагов экранирования! Поэтому, если вы хотите совместить строку с символом буквенного процента, вам нужно будет выполнить двойное обратное слэширование и сказать LIKE 'something\\%'. Или, если это в литературе PHP ", которая также использует escape-обратную косую черту, "LIKE 'something\\\\%'". Argh!

Это неверно в соответствии с ANSI SQL, в котором говорится, что: в строковых литералах обратные косые черты означают буквальные обратные косые черты и способ избежать одиночной кавычки ''; в выражениях LIKE по умолчанию не существует escape-символа.

Итак, если вы хотите LIKE-escape в переносном режиме, вы должны переопределить поведение по умолчанию (неправильное) и указать свой собственный escape-символ, используя конструкцию LIKE ... ESCAPE .... Для здравомыслия мы выберем что-то другое, кроме проклятой обратной косой черты!

function like($s, $e) {
    return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
}

$escapedname= mysql_real_escape_string(like($name, '='));
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";

или с параметрами (например, в PDO):

$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);

(Если вам нужно больше времени на переносимость, вы также можете повеселиться, пытаясь учитывать MS SQL Server и Sybase, где символ [ также является некорректным, особенным в инструкции LIKE и должен быть экранирован. argh.)