JackShcherbakov
@JackShcherbakov

Что автор имеет в виду в этом абзаце?

Здравствуйте! Читаю книгу Дэвида Скляра на английском. Дошел до баз данных. Уже несколько раз перечитал этот абзац, но не совсем понял автора. Что он имеет в виду? Что будет если использовать placeholder (символ замещения, если по-русски) в этой ситуации?
Вот собственно сам абзац
// First, do normal quoting of the value
$dish = $db->quote($_POST['dish_search']);
// Then, put backslashes before underscores and percent signs
$dish = strtr($dish, array('_' => '\_', '%' => '\%'));
// Now, $dish is sanitized and can be interpolated right into the query
$stmt = $db->query("SELECT dish_name, price FROM dishes
 WHERE dish_name LIKE $dish");

You can’t use a placeholder in this situation because the escaping of the SQL wild‐
cards has to happen after the regular quoting. The regular quoting puts a backslash
before single quotes, but also before backslashes. If strtr() processes the string first,
a submitted value such as %chicken% becomes \%chicken\%. Then, the quoting
(whether by quote() or the placeholder processing) turns \%chicken\% into
'\\%chicken\\%'. This is interpreted by the database to mean a literal backslash, fol‐
lowed by the “match any characters” wildcard, followed by chicken, followed by
another literal backslash, followed by another “match any characters” wildcard.
However, if quote() goes first, %chicken% is turned into '%chicken%'. Then, strtr()
turns it into '\%chicken\%'. This is interpreted by the database as a literal percent
sign, followed by chicken, followed by another percent sign, which is what the user
entered.

Заранее спасибо!

UPD:
Вопрос задал и на англоязычных форумах, но все равно не допер.
  • Вопрос задан
  • 1252 просмотра
Пригласить эксперта
Ответы на вопрос 3
EireenK
@EireenK
Если нужно экранировать wildcards (%, _) в строке для LIKE, плейсхолдер использовать не получится, т.к. quoting, выполняемый при подстановке в плейсхолдер, сбивает экранирование wildcard-ов:

Then, the quoting (whether by quote() or the placeholder processing) turns \%chicken\% into '\\%chicken\\%'.


Т.е. экранированные через strtr проценты снова превратились в полноценные wildcard-ы.

Чтобы экранирование wildcard-ов не слетало, quoting должен идти перед strtr(). Поэтому убираем плейсхолдер и вручную выполняем quote().
Ответ написан
Комментировать
R0dger
@R0dger
Laravel/Yii/2 AngularJs PHP RESTful API
Ответ написан
Комментировать
tsklab
@tsklab
Здесь отвечаю на вопросы.
Что автор имеет в виду в этом абзаце?
Вот для MS SQL LIKE, читать про escape_character.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы