Регистронезависимый поиск в MySQL (Проблема кодировки)

  • Автор темы Автор темы whitelex
  • Дата начала Дата начала

whitelex

Новичок
Регистронезависимый поиск в MySQL (Проблема кодировки)

Обычно не прошу помощи в делах программерских на форумах, пытаюсь до всего дойти сам юзая поиск и читая литературу, но тут ситуация уже просто безвыходная!

Срочно нужна ваша помощь, уже вторые сутки сижу и никак не могу решить проблему

Ситуация заключается в следующем:
Поставил движок поисковой машины sphider, настроил его так, чтобы сайты с различной кодировкой индексировал и перекодировал полученную информацию в одну кодировку cp1251. На локалке все записывается без проблем, поиск работает независимо от регистра. Но! Когда загружаю все файлы на сервер, переношу таблицы с теми же значениями, происходит следующее: в мускул данные не заносятся не так как на локалке, в phpmyadmin крякозябры, но поиск все-равно работает, только уже реагирует на регистр.

PHP:
@mysql_query("SET NAMES cp1251");
@mysql_query("SET collation_connection = cp1251_general_ci");
@mysql_query("SET collation_server = cp1251_general_ci");
@mysql_query("SET collation_database = cp1251_general_ci");
@mysql_query("SET character_set_client = cp1251");
@mysql_query("SET character_set_connection = cp1251");
@mysql_query("SET character_set_results = cp1251");
@mysql_query("SET character_set_server = cp1251");

PHP:
setlocale(LC_ALL, 'ru_RU.CP1251');

PHP:
.htaccess
AddDefaultCharset cp1251

Все варианты перебрал и НИЧЕГО.....

Пробовал всё, в UTF8 тоже не помогло...

Данные сервера:

PHP:
Variable_name Value
character_set_client utf8
character_set_connection utf8
character_set_database cp1251
character_set_filesystem binary
character_set_results utf8
character_set_server latin1
character_set_system utf8
character_sets_dir /usr/share/mysql/charsets/

Данные моего сервера:

PHP:
character_set_client cp1251
character_set_connection utf8
character_set_database cp1251
character_set_filesystem binary
character_set_results cp1251
character_set_server cp1251
character_set_system utf8
character_sets_dir usrlocalmysql5sharecharsets

Но это всё должно быть до лампы, если SETs прописаны...


Здесь на сайте решение проблемы описаны, но поверхностно... не помогает.
http://phpclub.ru/faq/Mysql41Rus

Симптомы:
Русский текст приходит в скрипт как русский, в консольном клиенте тоже все хорошо. Однако не работает сортировка, перевод в верхний/нижний регистр и т.д. Если применить решение из проблемы №1, то либо русский текст становится вопросами, либо mysql_error() возвращает сообщение похожее на «Illegal mix of collations (latin1_general_ci,IMPLICIT) and (cp1251_general_ci,COERCIBLE)...». В тоже время phpMyAdmin русский текст отображает как «крокозябры» (латинские символы с умляутами и т.д.).

Тестирование:
Попробуйте в phpMyAdmin-е выполнить запрос вида «SELECT CONVERT(CONVERT(поле USING binary) USING кодировка) FROM таблица», где таблица и поле соответствующая таблица и поле с русским текстом, а кодировка — кодировка из проблемы №1.

Результат тестирования:
Если буквы (но необязательно слова) стали русскими, значит текст в базе лежал не в правильной кодировке и его нужно сконвертировать.
Если буквы стали русскими, а слова нет («бнопня»), значит неверно выбрана одна из русских кодировок – пробуйте другие, пока не получится русских слов.

Решение:
1) Установить для My SQL нужную кодировку по умолчанию.
Внимание! Это решение сработает сработает, только если кодировки не переопределены для базы, таблицы или столбца.
Для этого нужно в файл my.cnf/my.ini в раздел [server] добавить следующую строку:
default-character-set=cp1251
2) Сконвертировать таблицы в нужную кодировку.
Про то как конвертировать таблицы с неверными кодировками хорошо написано в мануале. Повторять здесь то же самое не к чему.
 
в мускул данные не заносятся не так как на локалке
Ну, если ты так же все делаешь, как пишешь, то неудивительно, что ничего не работает.

что значит - "переношу таблицы с теми же значениями"?
какая версия мускуля на хостинге?
почему не привел еще одну, самую важную информацию о своих базах?

читай еще здесь: http://phpfaq.ru/charset
пока не прочтешь, ничего сюда не пиши.
 
Я ничего не переношу, имелось ввиду, что создавал таблицы с теми же данными, а сама таблица уже пополняется через выполнение скрипта.

Теперь данные заносятся отлично, но регистронезависимый поиск все-равно не работает как положено.. может ли это быть проблема сервера?

-~{}~ 06.11.08 03:51:

Проблема оказывается была в strtolower(), который не реагирует на русский язык!

Решил её таким образом:
$upper = 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
$lower = 'абвгдежзийклмнопрстуфхцчшщъыьэюя';
$phrase = strtr($phrase, $upper, $lower);
 
Проблема оказывается была в strtolower(), который не реагирует на русский язык!
mb_strtolower() если кодировка мультибайтная, и strtolower() и разбираться с локалью и кодировкой
 
whitelex
А зачем тебе
Решил её таким образом:
$upper = 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
$lower = 'абвгдежзийклмнопрстуфхцчшщъыьэюя';
$phrase = strtr($phrase, $upper, $lower);
Тебе средствами PHP не нужно в нижний регистр все переводить!

SET collation_connection = cp1251_general_ci
Не учитывает регистр при сравнение (case intensivity)

SET collation_connection = cp1251_general_cs
Учитывает регистр при сравнении (case sensivity)
 
Активист
collation_connection имеет смысл только при сравнении "литерал" cmp "литерал". на сравнения "литерал" cmp "поле" оно никакого влияния не оказывает
 
Ну да, затупил.

Вот пример для ТС

Код:
mysql> create database `test_cs`;
Query OK, 1 row affected (0.08 sec)

mysql> use `test_cs`;
Database changed

mysql> create table `test_collate`(`id` int unsigned not null primary key auto_increment, `text` text) default character set cp866 collate cp866_general_ci;
Query OK, 0 rows affected (0.10 sec)

mysql> insert into `test_collate` values (null, 'Бла Бла Бла Текст бла');
Query OK, 1 row affected (0.04 sec)

mysql> select * from `test_collate` where `text` LIKE '%';
+----+-----------------------+
| id | text                  |
+----+-----------------------+
|  1 | Бла Бла Бла Текст бла |
+----+-----------------------+
1 row in set (0.00 sec)

mysql> select * from `test_collate` where `text` LIKE '%Текст%';
+----+-----------------------+
| id | text                  |
+----+-----------------------+
|  1 | Бла Бла Бла Текст бла |
+----+-----------------------+
1 row in set (0.00 sec)

mysql> select * from `test_collate` where `text` LIKE '%текст%';
+----+-----------------------+
| id | text                  |
+----+-----------------------+
|  1 | Бла Бла Бла Текст бла |
+----+-----------------------+
1 row in set (0.00 sec)

mysql> create table `test_collate_bin`(`id` int unsigned not null primary key auto_increment, `text` text) default character set cp866 collate cp866_bin;
Query OK, 0 rows affected (0.09 sec)

mysql> insert into `test_collate_bin` values (null, 'Бла Бла Бла Текст бла');
Query OK, 1 row affected (0.04 sec)

mysql> select * from `test_collate_bin` where `text` like '%текст%';
Empty set (0.00 sec)

mysql> select * from `test_collate_bin` where `text` like '%Текст%';
+----+-----------------------+
| id | text                  |
+----+-----------------------+
|  1 | Бла Бла Бла Текст бла |
+----+-----------------------+
1 row in set (0.00 sec)

mysql>

и

Код:
mysql> set @@collation_connection = 'cp866_bin';
Query OK, 0 rows affected (0.00 sec)

mysql> select 'привет' = 'привет';
+---------------------+
| 'привет' = 'привет' |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.00 sec)

mysql> select 'привет' = 'Привет';
+---------------------+
| 'привет' = 'Привет' |
+---------------------+
|                   0 |
+---------------------+
1 row in set (0.00 sec)

mysql> set @@collation_connection = 'cp866_general_ci';
Query OK, 0 rows affected (0.00 sec)

mysql> select 'привет' = 'Привет';
+---------------------+
| 'привет' = 'Привет' |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.00 sec)
 
Сверху