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

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) Сконвертировать таблицы в нужную кодировку.
Про то как конвертировать таблицы с неверными кодировками хорошо написано в мануале. Повторять здесь то же самое не к чему.
 

Фанат

oncle terrible
Команда форума
в мускул данные не заносятся не так как на локалке
Ну, если ты так же все делаешь, как пишешь, то неудивительно, что ничего не работает.

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

читай еще здесь: http://phpfaq.ru/charset
пока не прочтешь, ничего сюда не пиши.
 

whitelex

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

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

-~{}~ 06.11.08 03:51:

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

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

zerkms

TDD infected
Команда форума
Проблема оказывается была в 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)
 

zerkms

TDD infected
Команда форума
Активист
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)
 
Сверху