Nyima
Guest
ЕСЛИ КОМУ ИНТЕРЕСНО ТО ЕСТЬ РЕШЕНИЕ РАЗ И НАВСЕГДА БЕЗ "SET NAMES" ПОД ВИНДУ!!!
Итак, после того как я обновивил свой PHP с версии 5.02 до версии 5.03 на моем локальном веб-сервере (апач 2.0.53) и MySQL 4.1.9 перестал должным образом работать PHP-NUKE 7.6, а именно - русские символы в названиях разделов форумов и именах юзеров стали отобоажаться вопросами, причем при использовании типа mysql4 в настройке нюка форум вообще не грузился и писал invalid mix collation, апгрейт на MySQL 4.1.10 застивил его грузится, но проблем с вопросами вместо кирилицы не исправил. Я пару раз почередовал PHP 5.02 с PHP 5.03 и понял что проблема именно в нем, причем в PHP 5.03 используется только одна либа - libmysql.dll - и для модуля php_mysql.dll и для модуля php_mysqli.dll - и имеет клиента версии 4.1.7 (теперь понятно почему у тех у кого был PHP 5.0.2 или PHP 5.0.1 были проблемы только с модулем php_mysqli.dll у которого версия клиета 4.1.7 и либа libmysqli, и не было проблем с модулем php_mysql.dll у которого версия клиента 3.23(22).x и либа libmysql, а вот у тех у кого PHP 5.0.3 проблемы и с тем и с тем модулем - а либа то у них ОДНА - и проблема в ней). Попав на этот форум и почитав много всего я применил для своего скрипта SET NAMES cp1251 и он помог - выдрал мне из таблицы nuke_authors имя "Нехристь", однако я понял из ваших постов что это не совсем круто, и так я сам все равно PHP-nuke не исравлю, а писать с такими задрочками диплом вообще никуда не идет. И я пошел по первой ссылке http://dev.mysql.com/doc/mysql/en/Charset-connection.html и вот что я понял:
character_set_server - кодировка всего сервера (любая база по умолчанию будет создаваться с этой кодировкой) - тут все понятно;
character_set_database - кодировка отделно взятой базы данных (например NUKE), любая таблица в этой базе будет по умолчанию создаваться с этой кодировкой, тут тоже все понятно;
character_set_client - кодировка в которой идет запрос от клиента к серверу - тут надо быть аккуратнее и понимать, что если мы запустим mysql.exe -u root -p password то кодировка символов самой командной строки (окна "доса") -сp866, а кодировка клиента(кодировка в которой идет запрос от клиента к серверу) по умолчанию latin1!!! и если мы ее не изменим (set character_set_client = cp866) то запрос вида: select * from nuke_authors where name = 'Нехристь' - возвратит ноль строк вместо одной в которой также будет и слово 'Нехристь'(нормальными символами - если character_set_results выставить в кодировку опять же нашего окна доса - сp866) - это произойдет потому (возврат нуля строк) что наши введенные символы с окна доса в кодировке сp866 будет переданы серверу как символы в другой! кодировке скажем сp1251 или utf8 или ucs2 или koi8u - и как бы сервер на перекодировал их (символы) там на приеме в другую кодировку (а в какую указывает переменная character_set_connection) все равно она не будет после перевода иметь соответствия нашим символам и в таблице такому запросу (а именно слову 'Нехристь' перекОВЕРКАНОМУ в результате неправильного указания кодировки клиенту 'set character_set_client = НЕ cp866' для отправки запроса серверу) не найдется соответствия и в ответе будет ноль строк;
character_set_results - кодировка в которой отправляются ответы от сервера к клиенту, здесь надо выставить кодировку в которой может отображать символы наш клиент (для нашего окна доса это cp866) и если эта переменная будет иметь другой параметр, например utf8 или сp1251 то вместо слова 'Нехристь' будут другие значки, но не вопросы;
character_set_connection - кодировка в которую должен перевести сервер символы из возможно другой (известной ему по переменной character_set_client) кодировки пришедшей от клиента, перед тем как ее (команду или запрос) обработать и отправить результат обратно клиенту. Тут впринципе даже если сервер переведет сначало запрос немного в другую (utf8 или ucs2 или сp866, но не latin1 и тому подобные в которых соответствующих символов нет) кодировку отличную от кодировки (например сp1251) используемой в таблице - запрос пройдет успешно и возвратит искомые записи (Нехристь) - видимо, если набор символов не теряется при первом переводе в кодировку заданую в character_set_connection, то сервер использует кодировки таблиц к которым обращается и умно сам перекодирует в них символы как-бы на лету и возвращает нам в кодировке character_set_results, а параметр задается для удобства чтоб лишний раз сервер не тратил время на перевод запроса в кодировку таблицы или таблиц (если они все имеют одинаковую кодировку то это выгодно и переводить нужно будет как раз только один раз и то если от клиента они идут в другой - как у нас в сp866 - кодировке ). Во всяком случае мой запрос
select * from nuke_authors where name = 'Нехристь' завершался с возвратом строки при любой из кодировок utf8 ucs2 сp866 ну и конечно же сp1251 назначенных переменной character_set_connection , но при условии что character_set_client = cp866 и естественно слово 'Нехристь' не отображалось в ответе чудо значками только при character_set_results = сp866 (все так и должно быть ведь у нас окно доса). Эти все наблюдения я проверял не только в досе но и в совершенно других условиях - ZEND Studio 4 и в PHPEd и в MySQL Query Browser и в EMS MySQL.
Из всего понятого мной (дочитать ту ссылку полностью так и не успел) пришел к выводу что надо заставить нашего клиента PHP - и конектится в нужной нам кодировке чтобы там на сервере ждали наши русские символы; и указать имя кодировки серверу для нашего соединения - чтоб он знал во что переводить или не переводить наши символы; и на последок заставить нашего клиента отображать результаты в той кодировке в которой они пришли. Почитав на форумах про то как тут собирали под линукс библиотеки с пшп путем указания параметров при компиляции, пришел к выводу что править dll - ку Hiew'ом, от которой столько проблем, для изменения в ней указания на кодировку, как это описано в соседнем форуме вовсе не безнадежно и попробовать можно:
Итак - запустил Hiew602, открыл libmysql.dll; нашел latin1 - заменил на сp1251; нашел latin1_bin - заменил на cp1251_bin; нашел сразу же рядом latin1_german2_ci - заменил на cp1251_general_ci, нашел рядом latin1_swedish_ci - заменил опять же на тот самый cp1251_general_ci (если тут вместо latin1_swedish_ci поставить cp1251_general_cs то скрипт будет выдавать на mysqli_character_set_name(con_id) ответ cp1251_general_cs, лучше поэтому ..._ci). количество символов у обоих кодировок одинаково - latin1_swedish_ci = cp1251_general_ci =17 символов. Сохраняем и смотрим - уже не плохо - запускается апачь с пшп, mysqli_character_set_name(con_id) выдает cp1251_general_ci, но русские символы выглядет вопросами, не закарлючками а именно вопросами!, а это пожоже значит что наш модуль для MySQL в PHP-хе не то что подбирает им какуюто другую не правильную кодировку и выводит в ней, а просто не находит ей вообще никакого соответствия, как будто о ней никогда и не слышал и не знал. Странно ведь libmySQL.dll которая лежит в каталоге MySQL точно такая же как она там знает о кодировках? а там во всяком случае в папке \MySQL\MySQL Server 4.1\share\charsets\ лежат себе какието xml файлы которые и описуют все кодировки! (напоминаю библиотека в папке bin каталога MySQL такаяже как и в папке PHP - не знаю может у меня она случайно както попала в папку bin и там ее быть не должно)Тут много говорили о том как PHP указать путь к некому файлу конфигурации MySQL'я чтоб PHP смог свою либу запустить с такими же параметрами как и МySQL запускает свою и понимает все кодировки, так вот этого делать не надо - надо просто указать либе где лежат кодировки или узнать где она их ищет!!! по умолчанию ( потому что она их просто не видит) и это записано в самой либе libmysql.dll (хотя есть парадокс - либа MySQL ищет их тамже по умолчанию где и либа лежащая в папке PHP, но либа или сервак MySQL все находит а PHP нет). Итак я открыл libmysql.dll лежaщей в папке PHP и нашел там строку:
/ charsets/ C:/mysql/ share Index.xml ucs2 .xml ¬c¤
немного не так отобразилась (на месте пробелов твердые знаки) но так даже понятней - вот тут то я и понял что это то место где либа ищет свои кодировки!!! ведь это основной файл (index.xml) для определения кодировок. Менять я тут ничего не стал, мои кодировки и файл index.xml лежат в папке D:\Program Files\MySQL\MySQL Server 4.1\share\charsets\
в строке котрую я нашел в либе небыло если смотреть слево направо от диска С:/ части пути \charsets\ а было сразу share - может надо както по частям воспринимать этот путь - адресация какая-то как старший байт, короче я решил на всякий случай скопировать содержимое папки D:\Program Files\MySQL\MySQL Server 4.1\share\charsets\ и в папку c:\mysql\share\ (что как оказалось не пригодилось) и в паку
c:\mysql\share\charsets\ (вот куда надо копировать кодировки!!! и PHP оживет навеки). Скопировал, перезапустил апач, закоментировал в своем скрипте set names сp1251 - оно свое отжило иииии О ЧУДО - Нехристь буковка в буковку, захожу на страницу php-nuke в форумы и все темы и все фамилии и все что в базе на русском то и тут тоже на родной кирилице сp1251.....как в старые добрые времена (2 дня назад ).
Итого: останавливаем Апач, открываем HIEW'ом файл libmysql.dll - меняем четыре строчки:
нашел latin1 - заменил на сp1251
нашел latin1_bin - заменил на cp1251_bin
нашел latin1_german2_ci - заменил на cp1251_general_ci
нашел latin1_swedish_ci - заменил на cp1251_general_ci
далее копируем содержимое папки ..\MySQL\MySQL Server 4.1\share\charsets\ в папку c:\mysql\share\charsets\ и запускаем Апач. Вот и все.
А все что было выше этих 9 строчек вступление в доме который построил Джек.
Есть решение! На абсолютную точность своего понимания не претендую поскольку сел за МySQL пару дней назад чтоб срочно написать диплом , но результат гарантирую на 100%.Автор оригинала: alldates
А не нашлось ли какого-нибудь решения, чтбы не добавлять в кучу скриптов SET NAMES 'cp1251';?
Меня интересует вариант под Windows.
Может что-то можно сделать на самом сервере?
Итак, после того как я обновивил свой PHP с версии 5.02 до версии 5.03 на моем локальном веб-сервере (апач 2.0.53) и MySQL 4.1.9 перестал должным образом работать PHP-NUKE 7.6, а именно - русские символы в названиях разделов форумов и именах юзеров стали отобоажаться вопросами, причем при использовании типа mysql4 в настройке нюка форум вообще не грузился и писал invalid mix collation, апгрейт на MySQL 4.1.10 застивил его грузится, но проблем с вопросами вместо кирилицы не исправил. Я пару раз почередовал PHP 5.02 с PHP 5.03 и понял что проблема именно в нем, причем в PHP 5.03 используется только одна либа - libmysql.dll - и для модуля php_mysql.dll и для модуля php_mysqli.dll - и имеет клиента версии 4.1.7 (теперь понятно почему у тех у кого был PHP 5.0.2 или PHP 5.0.1 были проблемы только с модулем php_mysqli.dll у которого версия клиета 4.1.7 и либа libmysqli, и не было проблем с модулем php_mysql.dll у которого версия клиента 3.23(22).x и либа libmysql, а вот у тех у кого PHP 5.0.3 проблемы и с тем и с тем модулем - а либа то у них ОДНА - и проблема в ней). Попав на этот форум и почитав много всего я применил для своего скрипта SET NAMES cp1251 и он помог - выдрал мне из таблицы nuke_authors имя "Нехристь", однако я понял из ваших постов что это не совсем круто, и так я сам все равно PHP-nuke не исравлю, а писать с такими задрочками диплом вообще никуда не идет. И я пошел по первой ссылке http://dev.mysql.com/doc/mysql/en/Charset-connection.html и вот что я понял:
character_set_server - кодировка всего сервера (любая база по умолчанию будет создаваться с этой кодировкой) - тут все понятно;
character_set_database - кодировка отделно взятой базы данных (например NUKE), любая таблица в этой базе будет по умолчанию создаваться с этой кодировкой, тут тоже все понятно;
character_set_client - кодировка в которой идет запрос от клиента к серверу - тут надо быть аккуратнее и понимать, что если мы запустим mysql.exe -u root -p password то кодировка символов самой командной строки (окна "доса") -сp866, а кодировка клиента(кодировка в которой идет запрос от клиента к серверу) по умолчанию latin1!!! и если мы ее не изменим (set character_set_client = cp866) то запрос вида: select * from nuke_authors where name = 'Нехристь' - возвратит ноль строк вместо одной в которой также будет и слово 'Нехристь'(нормальными символами - если character_set_results выставить в кодировку опять же нашего окна доса - сp866) - это произойдет потому (возврат нуля строк) что наши введенные символы с окна доса в кодировке сp866 будет переданы серверу как символы в другой! кодировке скажем сp1251 или utf8 или ucs2 или koi8u - и как бы сервер на перекодировал их (символы) там на приеме в другую кодировку (а в какую указывает переменная character_set_connection) все равно она не будет после перевода иметь соответствия нашим символам и в таблице такому запросу (а именно слову 'Нехристь' перекОВЕРКАНОМУ в результате неправильного указания кодировки клиенту 'set character_set_client = НЕ cp866' для отправки запроса серверу) не найдется соответствия и в ответе будет ноль строк;
character_set_results - кодировка в которой отправляются ответы от сервера к клиенту, здесь надо выставить кодировку в которой может отображать символы наш клиент (для нашего окна доса это cp866) и если эта переменная будет иметь другой параметр, например utf8 или сp1251 то вместо слова 'Нехристь' будут другие значки, но не вопросы;
character_set_connection - кодировка в которую должен перевести сервер символы из возможно другой (известной ему по переменной character_set_client) кодировки пришедшей от клиента, перед тем как ее (команду или запрос) обработать и отправить результат обратно клиенту. Тут впринципе даже если сервер переведет сначало запрос немного в другую (utf8 или ucs2 или сp866, но не latin1 и тому подобные в которых соответствующих символов нет) кодировку отличную от кодировки (например сp1251) используемой в таблице - запрос пройдет успешно и возвратит искомые записи (Нехристь) - видимо, если набор символов не теряется при первом переводе в кодировку заданую в character_set_connection, то сервер использует кодировки таблиц к которым обращается и умно сам перекодирует в них символы как-бы на лету и возвращает нам в кодировке character_set_results, а параметр задается для удобства чтоб лишний раз сервер не тратил время на перевод запроса в кодировку таблицы или таблиц (если они все имеют одинаковую кодировку то это выгодно и переводить нужно будет как раз только один раз и то если от клиента они идут в другой - как у нас в сp866 - кодировке ). Во всяком случае мой запрос
select * from nuke_authors where name = 'Нехристь' завершался с возвратом строки при любой из кодировок utf8 ucs2 сp866 ну и конечно же сp1251 назначенных переменной character_set_connection , но при условии что character_set_client = cp866 и естественно слово 'Нехристь' не отображалось в ответе чудо значками только при character_set_results = сp866 (все так и должно быть ведь у нас окно доса). Эти все наблюдения я проверял не только в досе но и в совершенно других условиях - ZEND Studio 4 и в PHPEd и в MySQL Query Browser и в EMS MySQL.
Из всего понятого мной (дочитать ту ссылку полностью так и не успел) пришел к выводу что надо заставить нашего клиента PHP - и конектится в нужной нам кодировке чтобы там на сервере ждали наши русские символы; и указать имя кодировки серверу для нашего соединения - чтоб он знал во что переводить или не переводить наши символы; и на последок заставить нашего клиента отображать результаты в той кодировке в которой они пришли. Почитав на форумах про то как тут собирали под линукс библиотеки с пшп путем указания параметров при компиляции, пришел к выводу что править dll - ку Hiew'ом, от которой столько проблем, для изменения в ней указания на кодировку, как это описано в соседнем форуме вовсе не безнадежно и попробовать можно:
Итак - запустил Hiew602, открыл libmysql.dll; нашел latin1 - заменил на сp1251; нашел latin1_bin - заменил на cp1251_bin; нашел сразу же рядом latin1_german2_ci - заменил на cp1251_general_ci, нашел рядом latin1_swedish_ci - заменил опять же на тот самый cp1251_general_ci (если тут вместо latin1_swedish_ci поставить cp1251_general_cs то скрипт будет выдавать на mysqli_character_set_name(con_id) ответ cp1251_general_cs, лучше поэтому ..._ci). количество символов у обоих кодировок одинаково - latin1_swedish_ci = cp1251_general_ci =17 символов. Сохраняем и смотрим - уже не плохо - запускается апачь с пшп, mysqli_character_set_name(con_id) выдает cp1251_general_ci, но русские символы выглядет вопросами, не закарлючками а именно вопросами!, а это пожоже значит что наш модуль для MySQL в PHP-хе не то что подбирает им какуюто другую не правильную кодировку и выводит в ней, а просто не находит ей вообще никакого соответствия, как будто о ней никогда и не слышал и не знал. Странно ведь libmySQL.dll которая лежит в каталоге MySQL точно такая же как она там знает о кодировках? а там во всяком случае в папке \MySQL\MySQL Server 4.1\share\charsets\ лежат себе какието xml файлы которые и описуют все кодировки! (напоминаю библиотека в папке bin каталога MySQL такаяже как и в папке PHP - не знаю может у меня она случайно както попала в папку bin и там ее быть не должно)Тут много говорили о том как PHP указать путь к некому файлу конфигурации MySQL'я чтоб PHP смог свою либу запустить с такими же параметрами как и МySQL запускает свою и понимает все кодировки, так вот этого делать не надо - надо просто указать либе где лежат кодировки или узнать где она их ищет!!! по умолчанию ( потому что она их просто не видит) и это записано в самой либе libmysql.dll (хотя есть парадокс - либа MySQL ищет их тамже по умолчанию где и либа лежащая в папке PHP, но либа или сервак MySQL все находит а PHP нет). Итак я открыл libmysql.dll лежaщей в папке PHP и нашел там строку:
/ charsets/ C:/mysql/ share Index.xml ucs2 .xml ¬c¤
немного не так отобразилась (на месте пробелов твердые знаки) но так даже понятней - вот тут то я и понял что это то место где либа ищет свои кодировки!!! ведь это основной файл (index.xml) для определения кодировок. Менять я тут ничего не стал, мои кодировки и файл index.xml лежат в папке D:\Program Files\MySQL\MySQL Server 4.1\share\charsets\
в строке котрую я нашел в либе небыло если смотреть слево направо от диска С:/ части пути \charsets\ а было сразу share - может надо както по частям воспринимать этот путь - адресация какая-то как старший байт, короче я решил на всякий случай скопировать содержимое папки D:\Program Files\MySQL\MySQL Server 4.1\share\charsets\ и в папку c:\mysql\share\ (что как оказалось не пригодилось) и в паку
c:\mysql\share\charsets\ (вот куда надо копировать кодировки!!! и PHP оживет навеки). Скопировал, перезапустил апач, закоментировал в своем скрипте set names сp1251 - оно свое отжило иииии О ЧУДО - Нехристь буковка в буковку, захожу на страницу php-nuke в форумы и все темы и все фамилии и все что в базе на русском то и тут тоже на родной кирилице сp1251.....как в старые добрые времена (2 дня назад ).
Итого: останавливаем Апач, открываем HIEW'ом файл libmysql.dll - меняем четыре строчки:
нашел latin1 - заменил на сp1251
нашел latin1_bin - заменил на cp1251_bin
нашел latin1_german2_ci - заменил на cp1251_general_ci
нашел latin1_swedish_ci - заменил на cp1251_general_ci
далее копируем содержимое папки ..\MySQL\MySQL Server 4.1\share\charsets\ в папку c:\mysql\share\charsets\ и запускаем Апач. Вот и все.
А все что было выше этих 9 строчек вступление в доме который построил Джек.