Подстановочный знак в подготовленном 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();