Подстановочный знак в подготовленном MySQLi, возвращающем плохие значения
Пожалуйста, просмотрите нижнюю часть этого сообщения для получения новейшей информации и текущего состояния
Следуя рекомендациям таких сообщений, как этот:
Использование подстановочных знаков в подготовленном операторе - MySQLi
У меня установлен мой оператор, и он работает без ошибок. Но он не возвращает правильные данные.
Мой оператор select имеет это для WHERE:
WHERE `Name` LIKE ? order by `Name`
Моя строка, чтобы настроить привязку, а затем фактическое привязку.
$whatToBind = '%'. $whatName .'%';
$stmt = $mysqli->prepare($selectStr);
$stmt->bind_param('s', $whatToBind);
$stmt->execute();
Когда я получу свое возвращение, он полностью пропустит записи, которые должны совпадать.
Например, если я отправлю в "Кен Л", я получаю записи для "Кен Линтон", но не "Кен Лотон". Если я ставлю "Лотона", я не получаю никакого возврата.
Это типичное поведение по всем направлениям. Если я нахожусь в поле номера телефона, я получаю возврат на "658", но нет возврата на "609-658".
Если кто-нибудь может понять меня, что мне не хватает, это будет здорово.
Возвращает пример, который показывает точные примеры, которые я имею в виду:
Неполная:
![введите описание изображения здесь]()
Пусто, хотя это не должно быть:
![введите описание изображения здесь]()
Возвращает все, включая запись, которая должна была быть с другими 2:
![введите описание изображения здесь]()
Вопросы для ответа:
Некоторые дополнительные вещи, чтобы проверить:
Проверьте, что набор символов взаимодействия с MySQL/PHP установлен правильно, как правило: $mysqli- > set_charset ( "utf8mb4" ); сразу после установления соединения с базой данных.
Он установлен в utf8. Несмотря на то, что он поступил так же, как это было установлено.
Можете ли вы показать какой-либо вывод из $mysqli- > error?
Ошибок нет. Только неполные возвращения
Вы можете показать нам весь ваш запрос SQL?
Он включен в захват экрана. Хотя, это просто простая строка. И это не объясняет, как выглядит подготовленный оператор.
Вы можете показать структуру Collation/MySQL столбца Names?
Это все utf8 в соответствии с GoDaddy phpMyAdmin
Можете ли вы показать, какое значение имеет значение $whatName перед привязкой?
Он находится в верхней части экрана. Это повторилось, чтобы показать это, прежде чем что-нибудь еще произойдет.
В этот момент я думаю, что проблема заключается в том, что происходит, когда поле, которое я ищу, имеет пробел или другой символ, который не является буквой. Не то, что я точно прохожу. Но больше похоже, что после того, как инструкция подготовлена, то, что подготовлено, не соответствует тому, что находится в поле поиска. Этого не происходит, когда вы просматриваете поле до того места, где оно существует. Вот почему "Кен" работает в 100% случаев, но "Лоутон" терпит неудачу полностью. Это после пробела.
Я пробовал все виды преобразования типа кодирования. И я пробовал различные методы конкатенации строки. Результаты, которые я получаю, либо не лучше, но и полностью нарушают его.
Осталось еще 21 час на эту щедрость, если у кого-то есть больше идей.
На этом этапе я был бы счастлив присудить 25 каждому из двух парней, которые предоставили лучшую информацию. Кажется несправедливым, чтобы вознаграждать одного, а не другого.
Ответы
Ответ 1
Обратите внимание, что детали этого ответа вряд ли разрешат этот вопрос самостоятельно. При моем дальнейшем тестировании я установил, что добавление подстановок %
или _
к строкам до их привязки не влияет на то, как они привязаны к запросу.
То, что вы в настоящее время пытаетесь сделать, это объединить данные ($whatName
) с инструкцией SQL %
с каждой стороны, а парсер готового заявления просто не имеет этого, поскольку он побеждает цели безопасности prepard заявления.
Итак, решение состоит в том, что вам нужно вручную объединить переменную в оператор LIKE только в точке вставки, а не раньше, как вы делаете в данный момент.
Пример ниже будет выполнен так, как вы планируете:
$selectStr = WHERE `Name` LIKE CONCAT('%',?,'%') ORDER BY `Name`
$whatToBind = $whatName;
$stmt = $mysqli->prepare($selectStr);
$stmt->bind_param('s', $whatToBind);
$stmt->execute();
Обратите внимание, что сочетание data
и query
никогда, пока не будет выполнен подготовленный оператор.
Заметка о UTF-8 и наборах символов в MySQL:
Не используйте набор символов utf8_
MySQL, поскольку они являются неполным подмножеством истинного UTF-8 и поэтому могут по-прежнему вызывать серьезные проблемы с распознаванием символов. Вместо этого вы хотите использовать набор символов utf8mb4_
/collations/etc.
Кодировка символов может быть связана с вашей проблемой, и я настоятельно рекомендую прочитать отличные ответы на этот вопрос о переполнении стека, а также использовать PHP mb_
многобайтовые строковые функции.
Некоторые дополнительные вещи для проверки:
-
Проверьте, что набор символов взаимодействия с MySQL/PHP установлен правильно, обычно с помощью: $mysqli->set_charset("utf8mb4");
сразу после установления соединения с базой данных.
-
Вы можете показать какой-либо вывод из $mysqli->error
?
-
Вы можете показать нам весь ваш SQL-запрос?
-
Можете ли вы показать структуру Collation/MySQL столбца Names
?
-
Можете ли вы показать, что значение $whatName
прямо перед привязкой? (в то время как ваш вопрос имеет смысл, наличие конкретного примера конкретной ситуации и конкретного результата, а также предполагаемый результат очень полезны для отладки.
-
Глупая вещь, но убедитесь, что у вас нет LIMIT
по вашим результатам!:-D
Ответ 2
Вероятно, это какая-то ошибка в кодировке в $whatName
.
Проверьте, является ли ваша переменная $whatName
переменной UTF8.
mb_detect_encoding($whatName, 'UTF-8', true) // should return true
если нет, то вам нужно будет использовать mb_detect_encoding
и mb_convert_encoding
на $whatName
, чтобы преобразовать его в utf8.
Если вы еще этого не сделали,
Установить правильную кодировку
$mysqli->set_charset('utf8mb4');
// if your MySQL version is lower than 5.5.3 then
// use $mysqli->set_charset('utf8');
перед вашим подготовленным выражением
$stmt = $mysqli->prepare($selectStr);
$stmt->bind_param('s', $whatToBind);
$stmt->execute();