Вопросительные знаки в ответах MySQL

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

Green Mother

Guest
Вопросительные знаки в ответах MySQL

Испортил сервер. После установки MySQL 4.1 все было нормально. После обновления mod_php4 до 4.3.11, MySQL стал возвращать знаки вопроса вместо русских букв. Кодировка в майскуле везде стоит cp1251_general_ci. Подскажите, куда копать?
phpinfo: http://service.rustex.ru/info.php
проблема: http://www.arescomputers.ru/
заранее благодарю.
 

Green Mother

Guest
Спасибо!
Выполнение в начале скрипта SET NAMES cp1251 помогает, а вот
init-connect="SET NAMES cp1251"
в my.cnf почему-то не действует.
На сервере около сотни сайтов, не хотелось бы все переделывать.
кусок my.cnf:
# The MySQL server
[mysqld]
default-character-set=cp1251
port = 3306
socket = /tmp/mysql.sock
init-connect="SET NAMES cp1251"

-~{}~ 10.05.05 16:36:

phpmyadmin показывает значения переменных:

Переменная Значение сессии Глобальное значение
character set client latin1 cp1251
character set connection latin1 cp1251
character set database cp1251 cp1251
character set results latin1 cp1251
character set server cp1251 cp1251
character set system utf8 utf8

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

-~{}~ 10.05.05 18:40:

Вопщем, перечитал я все что тут было по этому поводу. Как я понял, PHP как-то так устанавливает соединение, что дефолтовые значения соответствующих переменных, отвечающих за кодировки, почему-то сбрасываются в latin1.
Как это исправить - так и не понял.
init-connect="SET NAMES cp1251" - не работает, как только я с ним и с бубном не плясал.
пытался заменить файл latin1.xml на cp1251.xml - тоже не помогает.

У кого-нибудь работает init-connect="SET NAMES cp1251"?
Может у PHP есть свой какой-нибудь аналог my.cnf, где прописаны эти параметры?
 

DiTHER

bang bang
у php нет никаких параметров касательно кодировок, потому что их быть не может.

Можно только отправлять запросы вида "set names cp1251" и "set character set cp1251".

Конфигурация сервера MySQL:

my.cnf (приведены только касающиеся кодировок вещи)

[client]
default-character-set=koi8r
// это влияет НЕ НА КОДИРОВКУ СОЕДИНЕНИЙ. А на кодировку command-line утилитки mysql, которая под унихом - ессесно koi8r :)

character-sets-dir=/usr/share/mysql/charsets/

[mysql]
default-character-set=utf8
// насколько я помню это character-set-system, но может и нэт

[mysqld]
deafult-character-set=utf8
// character-set-database;
// character-set-server
// помойму овверрайдит значение в [mysql] для -set-system

после таких установок должно быть:

Код:
[size=2]mysql> show variables like '%chara%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | koi8r                      |
| character_set_connection | koi8r                      |
| character_set_database   | utf8                       |
| character_set_results    | koi8r                      |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
[/size]
Прим: (в указанном примере мы храним все базы в utf8, что кстати мне очень нравится :)).

Прим2: (установки -connection, -result, -client стоят таковыми изза [client] секции в my.cnf)

Итак. Только после указа таких настроек можно ложить что то в базу. (Все базы до этого будут "типа" в том чарсете -database который стоит по дефолту (а это latin1). То есть если у вас была база в mysql 3.x в koi8r, а вы переписали все файлики просто новому, то он будет думать что там latin1 кодировка, соответственно все перекодировочные операции будут неверны. Нужно mysqldump, либо (в случае огромных баз) select xx into outfile

Итак, все переписали и закинули. В общем сделали так что в базе кодировка именно такая, какая кодировка данных в ней.

запускаем через bash mysql, делаем простой запрос вида select, смотрим. Если русское видно - то все заеб*сь. Сервак прочитал utf8 с базы и переконвертил в koi8r.

Можно попробовать на скорую руку создать базу, таблицу, чего нибудь туда записать потом сделать запрос. После этого сбегать в /usr/lib/mysql/DBNAME/TABLENAME.MYD и посмотреть вручную примерную кодировку сего файла. Должон быть в utf8 :)

клиенту нужно полюбому сообщать в какой кодировке он хочет кушать данные.

Код:
[size=2]mysql> set names koi8r;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%chara%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | koi8r                      |
| character_set_connection | koi8r                      |
| character_set_database   | utf8                       |
| character_set_results    | koi8r                      |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
[/size]
видно что делает sat names

Код:
[size=2]mysql> set character set koi8r;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%chara%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | koi8r                      |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_results    | koi8r                      |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
[/size]
set character set делает почти тоже самое тока не задевает чарсет соединения (что плохо). Потому юзаем set names.

Резюме.
Важно чтобы вбазе было именно в той кодировке все в какой оно действительно есть там. Иными словами чтобы символы в файле *.myd были именно в той кодировке в какой типа эта таблица есть

После сих вещей клиентом ставим чарсет который ему нужен.

p.s. с этим ярые проблемы под виндой. Консольный клиент mysql упорно не хочет нормально выплёвывать русские символы, однако php+mysql4.1+apache под виндой сжились не хуже чем по *nix.

Спасибо за внимание (сам мучился хрен знает сколько).
Collations советую не юзать до тех пор пока действительно не нужна будет необходимость :)

без set names (которые по умолчанию пхп не отправляет) mysql думает что клиент хочет ту кодировку которая у него глобальный дефолт (latin1, задаётсяч при компиляции).

можно конешна перекомпилировать, но при переезде на другой сервак будут проблемы. Посему юзай set names при открытии соединяния. mysql3 пропусит это мимо ушей.
 

Green Mother

Guest
Мне не принципиальна utf8, буржуйских или еще каких сайтов тут нет, все базы в cp1251. По умолчанию, из консоли переменные имеют такой вид:
Код:
mysql> show variables like '%chara%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | cp1251                           |
| character_set_connection | cp1251                           |
| character_set_database   | cp1251                           |
| character_set_results    | cp1251                           |
| character_set_server     | cp1251                           |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/share/mysql/charsets/ |
+--------------------------+----------------------------------+
т.е. при компиляции я ему все задал, мол, cp1251 - дефолтовый, и никак иначе. Это похоже на мистику, т.к. сегодня я не делал с ним ничего, а вчера последнее, что сделал, это ползал по всем сайтам, расставлял везде SET NAMES cp1251. Сегодня опять решил разбираться, переменные стоят как надо (вчера там были latin1 местами, из php по крайней мере), сейчас попробовал убрать кое-где SET NAMES - все работает! Не знаю, то ли я чего нажал под конец, то ли скрипт у меня запущен, который авто repair и еще чето делает раз в неск. суток, хрен его знает, но что-то заработало, к сожалению, не знаю что именно %). Разбираться теперь уже не буду, а то опять че-нить сломаю кривыми ручками своими.
 

DiTHER

bang bang
без set names при соединении будет та же кодировка что указана при компиляции (latin1 у многих, т.к. не указывали при компиляции вообще). А писать set names полезно хотя бы потому, что при изменении кодировки базы, не придётся менять скрипты.
 

Green Mother

Guest
полезно, никто не спорит. но лазить по всем сайтам на сервере, выискивать где там у них у всех mysql_p?connect и расставлять везде set names я лично за@$ался. потому и интересно было общее решение.
 
Сверху