Почему подготовленное Mysqli заявление не экранирует подстановочные знаки (% и _) и обратную косую черту ( \)?
В качестве меры безопасности я использую подготовленное Mysqli заявление и bindvariables.
Мой код показан ниже:
$what = trim($_GET['what']);
$key_word = "%".$what."%";
$where_clause = " WHERE chair.company LIKE ? OR chair.business_category LIKE ? OR chair.summary LIKE ?";
$query = "SELECT chair.id_user, chair.company FROM chair" . $where_clause;
$con = @mysqli_connect($hostname,$username,$password, $database_name);
$stmt = mysqli_prepare($con, $query);
$bind = mysqli_stmt_bind_param($stmt, 'sss', $key_word, $key_word, $key_word);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$bind = mysqli_stmt_bind_result($stmt,$business_id,$company);
while (mysqli_stmt_fetch($stmt))
{
echo htmlspecialchars($company)."<br>";
}
Из документации:
В качестве альтернативы явному экранированию специальных символов многие MySQL API предоставляют возможность заполнителя, которая позволяет вставлять специальные маркеры в строку оператора, а затем привязывать к ним значения данных при выполнении оператора. В этом случае API заботится о экранировании специальных символов в значениях для вас.
Я могу использовать все символы на клавиатуре (за исключением \ % _) и экранироваться и соответствовать правильно. Моя проблема заключается в том, что этот подготовленный оператор не экранирует подстановочные знаки (% и _) и экранирующий символ (\). Когда я ищу% Он перечисляет все элементы в базе данных. И когда я ищу _ Он перечисляет все элементы. И при поиске (\), он не соответствует желаемому элементу.
Я нашел похожий Вопрос, но ответчик никогда не отвечал моему требованию, потому что мне нужно использовать подстановочный знак в моем запросе.
Другой ответ на вопрос говорит, что чтобы избежать их, используйте двойную обратную косую черту
Даже это не проблема безопасности, почему готовое заявление не ускользает от них? Есть ли какая-либо ошибка в том, как я использую это в своем коде? Как динамически избежать их? Какую функцию я могу использовать для этого?
1 ответ
Подготовленные заявления избегают \
должным образом. В противном случае они не будут создавать правильно отформатированные строковые литералы, что является основной целью подготовленных операторов.
Кроме того, %
а также _
только специальные символы LIKE
Сравнение, но не для строк в целом. Таким образом, нет необходимости избегать их вообще. Если вам нужно сбежать от них для LIKE
Для сравнения сделайте это явно:
$what = addcslashes($what, '%_');
Кроме того, LIKE
также поддерживает использование escape-символа, кроме \
:
mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
-> 1