Поблема с кодировкой на ZendServer
Рубрика: Разбор багов и ошибок
5 Апр. 2009 Пару дней назад столкнулся с очень распространенной проблемной среди разработчиков - кодировкой. Для меня эта проблема исчезла когда я начал вести все свои проекты на UTF-8 и забыл про существование такого слова как cp1251.
Но на моё удивление в базу кириллица мне перестала приходить. Я начал все по новому перепроверять. База данных у меня была в кодировке utf8_general_ci, все таблицы - в нейже. Даже сравнение на всех полях стояло utf8_general_ci..
Для того что бы Yii установило соединение в нужной кодировке в конфиге надо прописать:
'charset'=>'UTF8'
но и это у меня было прописанно!
Я попробовал добавить в табличку данные напрямую через phpMyAdmin - и они пришли в нормальной кириллице. На форуме поддержки Yii хорошие люди рассказали что phpMyAdmin при подключении сам говорит с какой кодировкой он будет работать.
Я подумал, а почему бы мне не залесть в кишки Yii и самому запросом не сказать что я хочу работать с UTF-8? Я так и сделал. Обычно кстати для этих целей служит файлик my.cnf - но в Zend Server-е я его к сожалению ненашол (его там скорее всего и нету).
Поэтому я открыл файл framework/db/CDbConnection.php и нашел функцию которая отвечает за соединение:
protected function initConnection($pdo)
{
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if($this->emulatePrepare && constant('PDO::ATTR_EMULATE_PREPARES'))
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);
if($this->charset===null)
return;
switch(strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)))
{
case 'pgsql':
$stmt=$pdo->prepare('SET client_encoding TO ?');
$stmt->execute(array($this->charset));
break;
case 'mysqli':
case 'mysql':
$stmt=$pdo->prepare('SET CHARACTER SET ?');
$stmt->execute(array($this->charset));
break;
}
}
Я её немного изменил чтобы по человечески сказать что я хочу UTF-8, и она у меня стала выглядеть вот так вот:
/**
* Initializes the open db connection.
* This method is invoked right after the db connection is established.
* The default implementation is to set the charset for MySQL and PostgreSQL database connections.
* @param PDO the PDO instance
*/
protected function initConnection($pdo)
{
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if($this->emulatePrepare && constant('PDO::ATTR_EMULATE_PREPARES'))
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);
if($this->charset===null)
return;
switch(strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)))
{
case 'pgsql':
$stmt=$pdo->prepare('SET client_encoding TO ?');
$stmt->execute(array($this->charset));
break;
case 'mysqli':
case 'mysql':
$stmt=$pdo->prepare('SET CHARACTER SET ?');
$stmt->execute(array($this->charset));
$pdo->query("set character_set_client='utf8'");
$pdo->query("set character_set_results='utf8'");
$pdo->query("set collation_connection='utf8_general_ci'");
break;
}
}
После таких вот махинацией - данные в базу стали приходить в нормальном виде.
Также это была не единственная ошибка по которой портились данные еще и при выводе на экран. Для вывода я использовал всем знакомую функцию - htmlentities.
Почему то я думал что по умолчанию она должна понять что в неё приходит UTF. Оказалось нетак, что б работать с UTF надо указать обязательный третий парраметр.
Т.е. должно быть примерно вот так вот:
htmlentities($comments->text, null, "UTF-8")
После всех описанных выше махинаций - у меня всё стало работать как часы.
Если хотите опубликовать этот материал у себя - пожалуйста, разместите ссылку на страницу откуда вы его взяли.
- Думаю стоит назвать сегодняшний день - Днем Капчи :) В принципе уверен найдется много любителей поизвращяться и превратить капчу ... "Математическая капча"
- Хочу вас обрадовать выходном новой версии замечательного Yii фреймворка. Данный релиз был немного задержан посравнению с обычным графиком, но ... "Yii Framework 1.0.5"
- Интеграция Zend/Pdf в Yii Framework...
next
Введение
Yii является одним из распостраненных PHP фреймворков. В этой статье мы рассмотрим пример интеграции библиотеки ... "Отображаем PDF на Yii при помощи Zend"

[adm] zolter
Было сказано: Суббота, 04 Апрель 2009
Вот кстати ссылка форум Yii где мы вместе решили эту проблему - http://www.yiiframework.com/forum/index.php/topic,1390.0.html

[guest] 0utPunk
Было сказано: Четверг, 16 Июль 2009
Я вылечил это строчкой AddDefaultCharset utf-8 в .htaccess, возможно, в Вашем случае тоже поможет.

[adm] zolter
Было сказано: Четверг, 16 Июль 2009
Не, не поможет.
Ваш вариант не вылечит кодировку базы к сожалению :)

[guest] Гость
Было сказано: Среда, 11 Ноябрь 2009
Я не совсем понял какое отношение Zend Server имеет к MySQL? При установке MySQL не ставится автоматом (или я не прав?) По крайней мере когда я на сервер ставил Zend Server CE после него отдельно устанавливал MySQL Server и my.cnf лежал в etc. Поясните пожалуйста - мне это весьма интересно, так как на продакшен планирую на него скинуть проект на Yii (хотелось бы быть готовым к неожиданностям).

[adm] zolter
Было сказано: Четверг, 12 Ноябрь 2009
Как видишь по скрину - я пользовался еще бетой когда он только появился и был полностью бесплатным. В то время как я его ставил - mysql поднимался вместе с Zend-ом, и была возможность управлять им через панель зенда. Я очень много файлов перелопатил но так отдельный конфиг-mysql-а не нашел что б исправить кодировку соединения. Поэтому пришлось править в самом движке Yii. На других вебсерверах все решается простой правкой конфига mysql


