Проведение диакритически чувствительного поиска - PullRequest
3 голосов
/ 03 октября 2011

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

В моей ситуации мне нужно иметь возможность конкретно сравнивать символы с верхним индексом инижние точки (т. е. ȧ & ạ) и некоторые другие более распространенные символы (á, ã и т. д.), но эти буквы могут быть любыми (ṡ, ṛ, ṫ, ḍ, ṅ и т. д.).Желаемый результат будет работать так: если я ищу «a», я получаю только «a», а если я ищу «ȧ», я получаю «ȧ» только как результат, а не «a» вместе с ним (безточка).

Я прочитал, что мне нужно использовать utf8_bin, и я попытался изменить оба сопоставления полей, сопоставления таблиц и сопоставления базы данных, но безуспешно.Вот код:

// "sound" is being passed in by an AJAX call 
$sound = $_POST['sound'];

$query = "SELECT * FROM sounds WHERE 'sound' = '$sound'";
$result = mysql_query($query);

// This is then sent back to my page.

Я также изучил COLLATE с небольшим успехом.Я, вероятно, неправильно понимаю его использование пробером:

// Attempting to covert the searched string into the utf8_bin format to match my db collations
$query = "SELECT * FROM sounds WHERE 'sound' = '$sound' COLLATE utf8_bin";

Когда я использую utf8_general_ci или utf8_unicode_ci, я получаю исключительный результат «a» или «ȧ», возвращая оба «ȧ» и «a».Однако, если я использую utf8_bin, я ничего не получаю при поиске любого из них.Я полагаю, это потому, что в моей базе данных при использовании utf8_bin это - "ṅ (PH)" (одна из моих записей) - преобразуется в это - "e1b98528504829".Так есть ли способ конвертировать мои поиски в тот же формат, прежде чем запрашивать их?Или просто лучший способ сделать эту работу?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 03 октября 2011

Я предполагаю, что ваши данные не нормализованы.Чтобы использовать последовательность сортировки utf8_bin, вам нужно работать с нормализованными данными.Как данные в базе данных, так и данные в запросе должны быть нормализованы.

Последовательность байтов e1 b9 85 представляет собой кодировку UTF-8 LATIN SMALL LETTER N WITH DOT ВЫШЕ (U + 1E45),но это может быть разложено на ЛАТИНСКОЕ МАЛЕНЬКОЕ ПИСЬМО N (U + 006E) + КОМБИНИРОВАННАЯ ТОЧКА ВЫШЕ (U + 0307).Кодировка UTF-8 для разложения будет 6e cc 87.Последовательности сортировки utf8_general_ci и utf8_unicode_ci позаботятся об этом автоматически, а utf8_bin - нет.

В отдельном примечании - вы не должны создавать запрос путем прямой интерполяции $sound.Это открывает огромную дыру в безопасности вашей системы, делая ее уязвимой для атак SQL-инъекций .Вместо этого используйте подготовленный оператор и привязку параметров.(В документации php есть пример того, как это сделать .)

0 голосов
/ 05 октября 2011

Ладно, с небольшой помощью друга я получил его на работу.Оказывается, это прекрасно работает и с сопоставлениями utf8_general_ci.

Моя первая проблема заключалась в том, как я ввел свои данные в свою базу данных.Для этого я использовал phpMyAdmin, который по какой-то причине не кодировал данные должным образом, и все мои корзины оказались неверными.Это было исправлено, просто написав свой собственный sql для ввода значений.

Во-вторых, я использовал PHP-функцию iconv () для кодирования данных, поступающих с веб-страницы.Эти два решения, взятые вместе, получили совпадающие значения, и весь скрипт прекрасно работает.

Спасибо всем за помощь и предложения ... очень ценю, и, поверьте мне, не пропал даром.Я потратил много времени на все это.

Ура!

...