Если у вас MySQL 4.x/5.x и ЛЮБЫЕ ПРОБЛЕМЫ С РУССКИМ - ЧИТАТЬ ЭТО!

Статус
В этой теме нельзя размещать новые ответы.

Profic

just Profic (PHP5 BetaTeam)
Если у вас MySQL 4.1 и любые проблемы с русскими буквами, то загляните вначале сюда!

Обновленное и более подробное описание проблем и способов решения проблем в MySQL 4.1 с русскими буквами смотрите в FAQ:

MySQL 4.1, проблемы с русскими буквами




-------- Добавление от DiMA -------
[size=+1]Если глючат кодировки, сортировка с русскими буквами не работает и т.п. - читаем:
Патч MySQL 5.х (Windows) для включения cp1251[/size]

Проверено на Apache2, PHP 5.0.4 и MySQL 5.0.11-beta:

1) Останавливаем Апач, открываем HIEW'ом файл libmysql.dll (из каталога PHP) - меняем четыре строчки:
latin1 заменить на сp1251
latin1_bin заменить на cp1251_bin
latin1_german2_ci заменить на cp1251_general_ci
latin1_swedish_ci заменил на cp1251_general_ci
C:/MySQL/ заменить на . (точку) и дополнить девятью нулями \x00 (символом с кодом нуль, а не нулями \x30)

2) Там, где лежит apache2.exe (т.е. в Apache/bin) создаем каталог share и в нем каталог charsets. В этот каталог Apache/bin/share/charsets копируем все файлы из MySQL/bin/share/charsets (хотя достаточно только Index.xml и cp1251.xml). Благодаря замене "C:/mysql" на "." (и забиванием дополняющего места нулями) библиотека будет искать кодировку в "./share/charsets"

3) Запускаем Апач - работает. И самое главное - не надо держать каталог C:\MySQL с хламом. Все файлы Apache/PHP будут брать со своего локального пути.

Аналогичный патч можно применить и к mysql.exe, mysqld-nt.exe, но смысла нет (в рамках данной темы). Смотрите по FileMonitor и фильтром "*1251*;*charset*" кто и в каком месте пытается искать файлы.

Ну, и просто в my.ini не забыть проверить наличие строк:
[mysqld]
basedir="c:/..../mysql/"
datadir="c:/..../mysql/data/"
character-sets-dir="c:/..../mysql/share/charsets"
default-character-set="cp1251"
default-collation="cp1251_general_ci"
character-set-server="cp1251"
(опцию init-connect можно не трогать - не работает)
 

Greed

Guest
А можно сделать так, чтобы не надо было после коннекта выполнять set names ? Классно было бы иметь возможность прописать кодировку в my.cnf. Может php читает какую-нибудь секцию оттуда. (Я правда покопавшись в исходниках не нашел, но может у меня банан в глазу ;) ? )
 

Profic

just Profic (PHP5 BetaTeam)
Хороший вопрос.
Под виндой и с ext/mysql - насколько я знаю, никак. Только set names ...
Под юниксами и с ect/mysql - использовать внешнюю либу, естественно от 4.1.х - с ней же коннектимся :)
Под виндами и с ext/mysqli - [m]mysqli_options[/m](). Либо говорим, какой конфиг юзать - что правильно, либо говорим какую комманду выполнить при коннекте - что имхо есть костыль.
Под юниксами и с ext/mysqli - аналогично юниксам и простому ext/mysql.
 

Greed

Guest
Ладно, поставим более конкретный вопрос. Заранее прошу прощения, что немного в тему не попадает.
Есть php 4.3.9 под FreeBSD с ext/mysql. Можно ли, ночего не ковыряя в исходниках это сделать. И, если можно, то пожалуйста опишите подробно, что надо делать ?
Т.е. интересует решение не через костыль вставленный в исходник и чтобы при этом скрипты менять не пришлось. Это хорошо, когда у тебя 1,2.. 10 сайтов, терпимо когда 100, но когда их тысячи :-[ ]
 

Profic

just Profic (PHP5 BetaTeam)
Сам не делал. Привожу вырезку из лога irc. Может чем поможет.
2004-10-20 14:17:06 <^Tonn> т.е. при дефолтной связке latin1 - latin1_swedish_ci даннные возвращаются на сайты нормально. а при cp1251 - cp1251_general_ci они все в ??? уходят
2004-10-20 14:17:06 <algo> то ты по адресу
2004-10-20 14:17:14 <^Tonn> algo, ура
2004-10-20 14:17:18 <algo> итак
2004-10-20 14:17:21 <algo> ты только мускль апдейтил
2004-10-20 14:17:23 <algo> или ПХП тоже
2004-10-20 14:17:30 <algo> нужно и то и другое апдейтнуть
2004-10-20 14:17:32 <^Tonn> php тоже
2004-10-20 14:17:33 <algo> какая система
2004-10-20 14:17:39 <algo> операционная
2004-10-20 14:18:05 <^Tonn> 5.2-RELEASE FreeBSD
2004-10-20 14:18:09 <algo> о
2004-10-20 14:18:11 <algo> у меня 5.2.1
2004-10-20 14:18:14 <algo> ну ты ваще по адресу
2004-10-20 14:18:20 <algo> короче, делай
2004-10-20 14:18:25 <algo> 1. деинсталь мускль сервер и клиент
2004-10-20 14:18:50 <algo> 2. ищи библиотеку libmysqlclient.so.* и переименовывай ее
2004-10-20 14:18:55 <algo> убирай со стандартного места
2004-10-20 14:18:57 <algo> если она осталась
2004-10-20 14:19:07 <algo> это где-то в /usr/local/share вроде
2004-10-20 14:19:37 <algo> Ж/usr/local/lib/mysql
2004-10-20 14:19:55 <algo> ну не суть важно, главное - оттуда нафиг убери
2004-10-20 14:20:17 <algo> переименуй в .bak
2004-10-20 14:20:20 <^Tonn> )
2004-10-20 14:20:29 <algo> 3. компиляй пхп БЕЗ mysql
2004-10-20 14:20:39 <algo> вообще без --with-mysql
2004-10-20 14:20:55 <algo> 4. зайди в /usr/ports/database/mysql41-server/
2004-10-20 14:20:59 <algo> и подредактируй Makefile
2004-10-20 14:21:27 <algo> добавь в опции configure строки --with-charset=cp1251 --with-collation=cp1251_general_ci
2004-10-20 14:21:44 <algo> сделай make clean
2004-10-20 14:22:09 <algo> проследи, чтобы был сделан clean и в mysql41-client
2004-10-20 14:22:22 <algo> какая версия ПХП ?
2004-10-20 14:22:30 <^Tonn> 4.3.9
2004-10-20 14:22:58 <algo> зайди в php4-mysql и удали директорию work если есть
2004-10-20 14:23:29 <algo> дальше компиляй и инсталь мускль41
2004-10-20 14:23:34 <algo> mysql41-server
2004-10-20 14:23:36 <algo> make install
2004-10-20 14:23:54 <algo> заходи в php4-mysql
2004-10-20 14:23:57 <algo> порт
2004-10-20 14:24:08 <algo> и компиль его - там будет mysql.so
2004-10-20 14:24:27 <algo> вроде бы, он по дефолту берет родную мускульную либу
2004-10-20 14:24:45 <algo> если это не так - посмотри, чтобы было --with-mysql=/usr/local
2004-10-20 14:24:51 <algo> скорее всего будет все ок
2004-10-20 14:24:56 <algo> собственно, это все
2004-10-20 14:25:11 <algo> в результате мускль скомпилится с правильным чарсетом и collation
2004-10-20 14:25:22 <algo> php(!) будет работать с правильным collation
2004-10-20 14:25:36 <algo> один еще момент
2004-10-20 14:25:44 <algo> базы данных, скорее всего, останутся с charset=latin1
2004-10-20 14:25:47 <algo> нужно сделать
2004-10-20 14:25:54 <algo> alter database ... charset=cp1251 для баз
...
2004-10-20 14:31:19 <algo> ну в общем,я написал
2004-10-20 14:31:31 <algo> Profic: у меня проблема была с ПХП
2004-10-20 14:31:40 <algo> если он собран со своей либой
2004-10-20 14:31:49 <algo> то коннектится с collation=latin1
2004-10-20 14:31:55 <Profic> algo$ а php нужно сказать, чтоб брал либу системную, а не свою
2004-10-20 14:32:04 <algo> ну я это написал
2004-10-20 14:32:04 <tony2001> и все нормально, русский текст показывается на ура
2004-10-20 14:32:04 <algo> выше
...
2004-10-20 14:35:01 <algo> да
2004-10-20 14:35:27 <algo> mysql Ver 14.6 Distrib 4.1.5-gamma, for portbld-freebsd5.2.1 (i386)
2004-10-20 14:35:31 <algo> Server characterset: cp1251
2004-10-20 14:35:31 <algo> Db characterset: cp1251
2004-10-20 14:35:31 <algo> Client characterset: cp1251
2004-10-20 14:35:31 <algo> Conn. characterset: cp1251
2004-10-20 14:35:33 <algo> крысота
2004-10-20 14:38:42 <^Tonn> сорри
2004-10-20 14:38:43 <^Tonn> character set system это что?
2004-10-20 14:39:01 <^Tonn> почуму оно у меня utf8?
2004-10-20 14:39:36 <algo> забей на няго
2004-10-20 14:39:42 <^Tonn> ок
2004-10-20 14:39:46 <^Tonn> ладно. спасибо
2004-10-20 14:40:10 <^Tonn> а ты в бд дамп заливал или папки просто скопировал?
2004-10-20 14:40:16 <Profic> ^Tonn$ это locale по большому счету
2004-10-20 14:40:17 <algo> ничего я не заливал
2004-10-20 14:40:23 <algo> ну дамп сделал
2004-10-20 14:40:26 <algo> но не пользовался им
2004-10-20 14:40:29 <algo> просто апдейт
2004-10-20 14:40:30 <^Tonn> понятно
2004-10-20 14:40:39 <algo> и чарсеты поменять у баз
2004-10-20 14:40:49 <algo> вот такая фигня
2004-10-20 14:41:04 <algo> я щас работаю с ПХП5
2004-10-20 14:41:05 <algo> во
2004-10-20 14:41:11 <algo> сервак production
2004-10-20 14:41:17 <^Tonn> то что я чарсет у базы сменил, а у таблиц в ней рни не сменились, это я что-то сделать забыл?
2004-10-20 14:41:20 <algo> такое впечатление, что он стал тормознутее
...
2004-10-20 14:43:05 <algo> короче я написал
2004-10-20 14:43:08 <algo> как я 2 сервера ставил
2004-10-20 14:43:12 <^Tonn> ок
2004-10-20 14:43:19 <algo> только я ставил php5
Если кратко, то при сборке php нужно использовать не встроенную либу-клиент (--with-mysql), а мускульную (--with-mysql=/path/to/mysql/install)
 

Greed

Guest
Тоже кривой вэй. Т.к. не все клиенты используют одну и туже кодировку. А тут придется все заточить под cp1251 или чего-нибудь в этом духе. Тоже не выход ...
Profic ... PHP5 BetaTeam. Может напишешь авторам, что неплохо бы сделать, чтобы клиент mysql в php какую-нибудь секцию из my.cnf читал. :) Поправить не долго, но просто не хочется это делать при каждом обновлении php.
 

Sizz

Новичок
так есть же уже все, и в my.cnf прописать можно, прочтите мануал все-таки:

4.6.1 Набор символов, применяющийся для записи данных и сортировки

По умолчанию в MySQL используется набор символов ISO-8859-1 (Latin1) с сортировкой согласно шведским/финским правилам. Этот набор символов также подходит для использования в США и Западной Европе.

Все стандартные исполняемые файлы MySQL компилируются с настройкой --with-extra-charsets=complex. Таким образом в файл помещается код, позволяющий всем стандартным программам работать с набором символов latin1, а также многобайтовыми наборами символов. Другие наборы символов могут загружаться из соответствующих файлов определений по необходимости.

Набор определяет, какие символы могут использоваться в именах, а также способ сортировки значений в операторах ORDER BY и GROUP BY команды SELECT.

При запуске сервера можно изменить набор символов при помощи параметра --default-character-set. Выбрать доступные наборы символов можно при помощи параметров --with-charset=charset и --with-extra-charsets= список-кодировок | complex | all, и файлов наборов символов, перечисленных в SHAREDIR/charsets/Index. See section 2.3.3 Типичные опции configure.

При смене набора символов во время работы MySQL (что может одновременно изменить и порядок сортировки) необходимо запустить команду myisamchk -r -q --set-character-set=charset для всех таблиц. В противном случае индексы могут быть созданы в неправильном порядке.

При подключении клиента к серверу MySQL сервер отправляет ему используемый по умолчанию набор символов. На время соединения клиент переключается на использование этого набора.

Для экранирования строк в SQL-запросе необходимо пользоваться функцией mysql_real_escape_string(). mysql_real_escape_string() идентична старой функции mysql_escape_string() - во всем, кроме одного: в качестве первого параметра она принимает дескриптор соединения MYSQL.

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

Сделать это можно путем внесения в файл настроек MySQL следующей строки:

[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets

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

Заставить клиента использовать определенный набор символов можно следующим образом:

[client]
default-character-set=character-set-name

но обычно этого не требуется.

http://dev.mysql.com/doc/mysql/ru/Character_sets.html
 

Greed

Guest
Я тоже умею читать документацию.
Дак вот, php 4.3.9 секцию [client] из my.cnf не читает.
По крайней мере я не заметил никаких изменений с добавлением этих строк. Как приходили русские буквы вопросиками, так и приходят.
SET NAMES помогает, но это не есть прямое решение :)
 

Sizz

Новичок
>> Дак вот, php 4.3.9 секцию [client] из my.cnf не читает.
так и не должен

mysql_client_encoding ()
что выдает?

[client]
default-character-set=character-set-name

я так понимаю, если php использует либу мускульную (--with-mysql=/path/to/mysql/install), то этот клиент mysql и будет считывать эту строку. а если использовать либу идущую с php - там нет поддержки никаких кодировок кроме Latin-1 (ну может еще какая..)
поэтому, сделай как profic говорит, собери все с внешнией либой, добавь в MySQL все кодировки нужные, или вообще все:
--with-charset=windows-1251
--with-extra-charsets= all

и должно все заработать
 

Greed

Guest
Ну SET NAMES то их находит, или я чего-то не понимаю ?
 

Sizz

Новичок
Greed
когда ты вызываешь SET NAMES, то клиент ищет и подгружает эти наборы символов из файлов
в следующий раз при его запуске, надо опять все повторять

а так можно сразу с ними собрать.
 

slach

Новичок
Sizz

скажи мне пожалуйста
ГДЕ в английской версии документации

http://dev.mysql.com/doc/mysql/en/Charset-connection.html

ты увидел ссылку на раздел
[client]
в my.cnf
??

-~{}~ 02.12.04 17:21:

ой
был не прав

http://dev.mysql.com/doc/mysql/en/Character_sets.html

-~{}~ 02.12.04 17:28:

или все же я был прав

http://dev.mysql.com/doc/mysql/en/Character_sets.html
посмотрите комментарии

походу дела, кроме SET NAMES ... никакого ясного решения НЕТ...
блин
чего делать с переездом ??
 

Greed

Guest
Вот что написал я :)
/usr/local/libexec/mysqld --verbose --help все правильно после этого показывает, но php все равно русские символы вопросиками выводит. Народ, если это можно сделать, то напишите честно: у меня работает и скажите как вы это сделали (не собирая mysql и php "под себя"). Если таких нет, то не надо меня кормить советами.

evm# more /etc/my.cnf
[mysqld]
skip-innodb
character-sets-dir=/usr/local/share/mysql/charsets/
default-character-set=koi8r
default-collation=koi8r_general_ci
#log=/var/log/mysql.log

[mysql]
default-character-set=koi8r
character-sets-dir=/usr/local/share/mysql/charsets/

[client]
default-character-set=koi8r
character-sets-dir=/usr/local/share/mysql/charsets/
evm# ls -la /usr/local/share/mysql/charsets/
total 196
drwxr-xr-x 4 root wheel 512 Jun 3 2004 .
drwxr-xr-x 52 root wheel 512 Nov 24 12:43 ..
-r--r--r-- 1 root wheel 17147 Nov 14 12:50 Index.xml
-r--r--r-- 1 root wheel 1758 Nov 14 12:50 README
-r--r--r-- 1 root wheel 5528 Nov 14 12:50 armscii8.xml
-r--r--r-- 1 root wheel 5514 Nov 14 12:50 ascii.xml
-r--r--r-- 1 root wheel 6579 Nov 14 12:50 cp1250.xml
-r--r--r-- 1 root wheel 8364 Nov 14 12:50 cp1251.xml
-r--r--r-- 1 root wheel 5577 Nov 14 12:50 cp1256.xml
-r--r--r-- 1 root wheel 8910 Nov 14 12:50 cp1257.xml
-r--r--r-- 1 root wheel 5514 Nov 14 12:50 cp850.xml
-r--r--r-- 1 root wheel 5530 Nov 14 12:50 cp852.xml
-r--r--r-- 1 root wheel 5621 Nov 14 12:50 cp866.xml
-r--r--r-- 1 root wheel 6537 Nov 14 12:50 dec8.xml
-r--r--r-- 1 root wheel 5524 Nov 14 12:50 geostd8.xml
-r--r--r-- 1 root wheel 5736 Nov 14 12:50 greek.xml
-r--r--r-- 1 root wheel 5519 Nov 14 12:50 hebrew.xml
-r--r--r-- 1 root wheel 5510 Nov 14 12:50 hp8.xml
-r--r--r-- 1 root wheel 5537 Nov 14 12:50 keybcs2.xml
-r--r--r-- 1 root wheel 5518 Nov 14 12:50 koi8r.xml
-r--r--r-- 1 root wheel 6540 Nov 14 12:50 koi8u.xml
-r--r--r-- 1 root wheel 9818 Nov 14 12:50 latin1.xml
-r--r--r-- 1 root wheel 7256 Nov 14 12:50 latin2.xml
-r--r--r-- 1 root wheel 5674 Nov 14 12:50 latin5.xml
-r--r--r-- 1 root wheel 7446 Nov 14 12:50 latin7.xml
-r--r--r-- 1 root wheel 8055 Nov 14 12:50 macce.xml
-r--r--r-- 1 root wheel 8066 Nov 14 12:50 macroman.xml
-r--r--r-- 1 root wheel 6538 Nov 14 12:50 swe7.xml
 

Sizz

Новичок
slach
Группа client обеспечивает возможность задавать параметры, относящиеся ко всем клиентам MySQL (кроме самого mysqld). Эта группа великолепно подходит для указания пароля, используемого при подсоединении к серверу (но при этом следует убедиться, что разрешение на чтение и запись этого файла есть только у вас).

http://dev.mysql.com/doc/mysql/ru/Option_files.html
 

slach

Новичок
на чтения стоят права для MySQL

в итоге все решилось банальной пересборкой из портов mysql4.1-client

через

make WITH_CHARSET=cp1251 WITH_XCHARSET=all WITH_COLLATION=cp1251_general_ci
 

Neyro

Guest
Помогите-как в винхп сделать тож самое (поставить в пхп кодировку cp1251) ??
 

Profic

just Profic (PHP5 BetaTeam)
где? в php? а причем здесь mysql? да и нет "в php" никакой кодировки. ты форумом/топиком случайно не ошибся?
 

Spadver

Guest
Я тоже с этим столкнулся!
При заливании дампа - сплошные знаки вопросов вместо русского! :(
Сначала грешил на версию phpmyadmin - 2.6.0 - pl3

Хостер сказал
Надо в /etc/my.cnf прописать.
[client]
default-character-set = cp1251
Сделал.
Но этого оказалось недостаточно.

Теперь делаю так:
(работаю на сервере через ISPManager)
1. Создаю базу и пользователя для нее
2. Запускаю phpmyadmin и открываю новую (ПУСТУЮ) базу.
И сразу же выставляю кодировку для сравнения - из набора 1251 (точно не помню - с заглавными русскими буквами)
После этого phpmyadmin формирует и выполняет какой-то запрос где присваивает таблицу символов - с1251 и таблицу для сравнения.
3. После этого захожу в раздел SQL и выбираю кодировку заливаемого файла c1251 и указываю на сам файл.

Вот так вроде работает!

Но что будет при чтении дампа из командной строки (используя SSH) пока не пробовал (Только начал разбираться с этим :) )
Но, полагаю что какие-то ключи надо бы указать (для указания 1251 как в п.3)

-~{}~ 12.01.05 17:56:

Еще раз перечитал топик и проверил у себя:
1.
После этого phpmyadmin формирует и выполняет какой-то запрос где присваивает таблицу символов - с1251 и таблицу для сравнения
Конкретно формирует SQL-запрос:
ALTER DATABASE `ИМЯ_БАЗЫ` DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_cs
2. При пробном запуске дампа (создание таблицы
а) в начале добавляет
Это вроде бы хорошо
б) в конце добавляет
SET CHARACTER SET utf8;
SET SESSION collation_connection = 'utf8_general_ci';
Что мне не нравится.

3. Здесь предлагается перекомпилировать связку PHP MySQL
Но... я этого не умею.
Но у меня есть root доступ.

Может можно обойтись перепрописыванием конфигов?
Где и как?

Или просить хостера?
 

Вдул

Guest
А чтоб не мучиться - легкий путь... Поставь тип поля binary...
 

alldates

Guest
А не нашлось ли какого-нибудь решения, чтбы не добавлять в кучу скриптов SET NAMES 'cp1251';?
Меня интересует вариант под Windows.
Может что-то можно сделать на самом сервере?
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху