#php #mysql
#php #mysql
Вопрос:
Я хочу, чтобы наш модуль поиска мог выполнять поиск по ключевым словам, таким как *lex. Использование * для замены букв перед этим. Я обнаружил, что%, который я добавляю в свой запрос, не работает и возвращает ошибку. Пожалуйста, помогите мне взглянуть на мой код. Спасибо
if(substr($searchfirst_name, 0, 1) == '*'){
$subquery .= " AND first_name LIKE %".Formatter::sql($searchfirst_name);
}elseif(substr($searchfirst_name, -1, 1) == '*'){
$subquery .= " AND first_name LIKE ".Formatter::sql($searchfirst_name)."%";
}else{
$subquery .= " AND first_name LIKE ".Formatter::sql($searchfirst_name);
}
Я думаю, что проблема связана с функцией Formatter::sql() . Он фильтрует переменную и добавляет к ней косую черту. Как мне изменить или создать новую функцию для этого?
public static function sql($value, $fieldName = false) {
if($fieldName) {
return '`' . $value . '`';
}
else if( is_string($value) ) {
return ''' . addslashes($value) . ''';
}
else if($value === null) {
return 'NULL';
}
else if($value === true) {
return 1;
}
else if($value === false) {
return 0;
}
else if( is_numeric($value) ) {
return $value;
}
else {
return ''' . addslashes($value) . ''';
}
}
Комментарии:
1. У вас есть ссылка на
Formatter::sql
документацию или код для нее? Вам нужно посмотреть, есть ли у него другой параметр, чтобы автоматически не включать кавычки.2. Я предполагаю, что ошибка выглядит примерно так:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%
Ответ №1:
Я думаю, вы должны использовать кавычки:
LIKE '%...'
или LIKE '...%'
ОТРЕДАКТИРОВАНО:
Ну, теперь ошибка ясна:
запрос, выполняемый с использованием formatter, похож .... LIKE %'....'
на что-то совершенно неправильное.
При использовании LIKE
предложения не используйте форматировщик, а используйте $searchfirst_name
напрямую!!
Комментарии:
1. @AlexHu: не могли бы вы показать нам вывод
Formatter::sql($searchfirst_name)
, пожалуйста?2. спасибо за ваш ответ. Я редактирую свой вопрос, пожалуйста, посмотрите
3. Я знаю это, но это приведет к большой дыре в безопасности SQL-инъекции
4. @AlexHu: перепишите часть команды Formatter.sql, чтобы включить подобный синтаксис, это довольно просто. Вы можете использовать другой параметр в определении функции и другой параметр if в теле для создания правильного синтаксиса…
Ответ №2:
Попробуйте это
if(substr($searchfirst_name, 0, 1) == '*'){
$subquery .= " AND first_name LIKE '%".Formatter::sql($searchfirst_name)."'";
}elseif(substr($searchfirst_name, -1, 1) == '*'){
$subquery .= " AND first_name LIKE '".Formatter::sql($searchfirst_name)."%'";
}else{
$subquery .= " AND first_name LIKE '".Formatter::sql($searchfirst_name)."'";
}
Комментарии:
1. Можете ли вы сохранить результат Formatter::sql($searchfirst_name) в переменной, а затем попытаться поместить его в запрос.
Ответ №3:
Первые два выглядят нормально, но ваш третий не может быть ПОХОЖИМ. Смотрите ниже.
if(substr($searchfirst_name, 0, 1) == '*'){
$subquery .= " AND first_name LIKE %".Formatter::sql($searchfirst_name);
}elseif(substr($searchfirst_name, -1, 1) == '*'){
$subquery .= " AND first_name LIKE ".Formatter::sql($searchfirst_name)."%";
}else{
$subquery .= " AND first_name = ".Formatter::sql($searchfirst_name);
}
Ответ №4:
У вас был% вне строковых кавычек, и вам, вероятно, тоже нужно избавиться от символов *
Поэтому вместо целого, если construct:
$subquery .= " AND first_name LIKE ".str_replace('*','%',Formatter::sql($searchfirst_name));
но будьте осторожны, это дает возможность заменять * везде в строке
Ответ №5:
Просто сделайте:
if(substr($searchfirst_name, 0, 1) == '*'){
$subquery .= " AND first_name LIKE ".Formatter::sql('%'.$searchfirst_name);
}elseif(substr($searchfirst_name, -1, 1) == '*'){
$subquery .= " AND first_name LIKE ".Formatter::sql($searchfirst_name.'%');
}else{
$subquery .= " AND first_name LIKE ".Formatter::sql($searchfirst_name);
}
Это будет работать, потому что функция escape в Formatter::sql
не повлияет на ‘%’
В вашей sql
функции замените addslashes
на функцию escape, предоставленную базой данных, например, mysql_real_escape_string . Всегда используйте механизм базы данных для экранирования строк (или, что еще лучше, используйте параметризованные запросы с PDO).