Проблема с запросом LIKE MySQL

У меня есть следующий запрос MySQL, который я выполняю со страницы .php

SELECT * FROM servers WHERE name LIKE '%$value%'

который при выполнении выбирает 0 строк (однако запрос выполняется успешно, поэтому я не могу использовать mysql_error() для отладки). Когда я запускаю запрос в PHPMyAdmin, он выбирает соответствующие строки. Другие запросы, такие как

SELECT * FROM servers

работать нормально. Я могу разместить свой код здесь, если это поможет.


person ahota    schedule 07.07.2011    source источник
comment
так в чем у тебя проблема?   -  person rackemup420    schedule 08.07.2011
comment
Было бы полезно увидеть код, о котором вы говорите. Кроме того, не помешает привыкнуть цитировать ваши идентификаторы. .   -  person Justin ᚅᚔᚈᚄᚒᚔ    schedule 08.07.2011
comment
Я выполняю поиск на своем веб-сайте, поэтому $value — это строка символов. И да, он проходит через mysql_real_escape_string() и stripslashes().   -  person ahota    schedule 08.07.2011


Ответы (3)


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

  1. PHP заменяет переменные внутри строк в двойных кавычках, но не внутри строк в одинарных кавычках.
  2. Один символ кавычки просто обрабатывается как обычный символ в строке, ограниченной другим.

Собрав это вместе, вы можете написать:

$q = "SELECT * FROM servers WHERE name LIKE '%$value%'"; //Fine

Вы не можете написать:

$p = 'SELECT * FROM servers WHERE name LIKE "%$value%"'; //Broken!

$q работает, потому что это строка в двойных кавычках, а апострофы — обычные символы. $p не работает, потому что это строка в одинарных кавычках.

Как указал GoodFather ниже, вы также можете сказать ${value}, чтобы избежать двусмысленности с внешней строкой, например. $r = "ABC${value}DEF";.

person Kerrek SB    schedule 07.07.2011
comment
@ yes123: ты проверял это? У меня работает нормально! - person Kerrek SB; 08.07.2011
comment
@ yes123: вопрос был не в этом. Насколько нам известно, у OP есть $value = mysql_real_escapestring($data, $link); или что-то в этом роде. - person Kerrek SB; 08.07.2011
comment
насколько мы знаем, у него есть mysql_real_escape? лол и откуда ты это знаешь? И даже если вы знаете, что у него это есть, вы должны предложить ему использовать PDO. ВСЕГДА. - person dynamic; 08.07.2011
comment
о, ты достаточно умен, чтобы создать свой собственный ответ, озадаченный чужими ответами .. мммм - person Marek Sebera; 08.07.2011
comment
@yes: да, да, хорошо, но на самом деле вопрос был не в этом ... хотя, конечно, оставьте комментарий для ОП. - person Kerrek SB; 08.07.2011
comment
даже если вопрос не в этом, вы никогда не должны предлагать ему использовать $var в SQL. - person dynamic; 08.07.2011
comment
@yes: вы, конечно, правы - почему бы не написать свой собственный ответ, чтобы предложить это? Марек: Извините, я как бы имел в виду, что это исправление вашего первоначального ответа, но оно ускользнуло от меня ... Я снимаю отрицательный голос! - person Kerrek SB; 08.07.2011
comment
@yes: Эй, у тебя репутация за то, что ты проголосовал за ответы, почему бы тебе не это сделать? ;-) - person Kerrek SB; 08.07.2011
comment
@Kerrek, конечно, я ценю твою прямоту, я сделал то же самое для тебя - person Marek Sebera; 08.07.2011

Вам действительно нужно посмотреть на выполнение этого запроса более безопасно. Это поможет и в вашей проблеме. В нынешнем виде вы уязвимы для SQL-инъекций. Посмотрите примеры из руководства по PHP, как это сделать правильно:

http://php.net/manual/en/function.mysql-query.php

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

Например, вы можете переписать оператор запроса (на PHP) следующим образом:

$query = sprintf("SELECT * FROM servers WHERE name LIKE '%". mysql_real_escape_string($value) . "%'");

Это очистит ваш код, а также решит проблему с некорректной работой оператора LIKE.

Вот еще хорошая статья на эту тему:

http://joshhighland.com/blog/2008/07/06/php-sprintf-sql-like/

person IAmTimCorey    schedule 07.07.2011
comment
это не отвечает на его вопрос, правила безопасности кода не решат его проблемы с синтаксисом. Если это часть внутреннего администрирования скриптов, угроз безопасности нет вообще. - person Marek Sebera; 08.07.2011
comment
@Marek - я обновлял свой ответ примером кода, чтобы объяснить его, когда вы разместили этот комментарий. Что касается вашего мнения об использовании этого в качестве внутреннего скрипта без опасности, мое мнение таково, что вы НИКОГДА не пишете уязвимый код. Даже если сейчас он используется внутри компании, может наступить день, когда назначение кода изменится. Кроме того, даже внутренний код должен быть защищен от подобных проблем. Кто знает, какой младший админ на самом деле выполняет этот скрипт. Они могут нанести реальный ущерб, если вы не будете осторожны. Делать это правильно с первого раза всегда лучше. - person IAmTimCorey; 08.07.2011
comment
согласен с вами, но не нужно зацикливаться на уязвимости кода, когда нужно создать работающий код. Безопасность и оптимизация являются частью дальнейших шагов после создания работающей системы. Конечно, я согласен с необходимостью безопасности и с тем, что мы не можем сказать, как он сейчас использует этот код, но он не работает, а код SECURE непригоден для использования;) - person Marek Sebera; 08.07.2011
comment
@Марек - я понимаю. Я просто нервничаю, когда вижу что-то подобное. Есть так много способов, которые могут пойти не так. Это особенно верно, когда мы размещаем код на таком сайте. Даже если ОП правильно обрабатывает код (он так и делает), у кого-то другого, у кого есть аналогичная проблема, может не быть. Я предпочитаю иметь безопасный код, который не работает, а не работающий незащищенный код (можете ли вы сказать, что я несу ответственность за безопасность данных? :) Кажется, что что-то всегда происходит, и добрые намерения исправить проблемы безопасности становятся забыли, потому что это работает. Это был мой опыт. - person IAmTimCorey; 08.07.2011

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

person Glazius    schedule 07.07.2011