Наши заметки о MODx
В этом разделе мы будем собирать небольшую копилку секретов по работе с системой управления контентом сайта (CMS) MODx. Эти заметки ни в коем случае не претендуют на лавры документации. На нашем сайте тема MODx вообще занимает небольшой уголок, и эти материалы мы размещаем только потому, что по роду основной работы нам приходится оказывать техническую поддержку нескольким десяткам организаций, использующих наши прототипы сайтов. В то же время кое-что может пригодиться и другим людям.
Мы не претендуем на изложение "истины в последней инстанции". Наверняка в этих заметках гуру MODx найдут неточности и ошибки. Мы будем очень благодарны, если на это нам укажут в комментариях.
В заметках мы стараемся не просто сразу приводить готовое правильное решение, но и показываем, как мы набивали шишки в процессе поиска.

О проблемах с кодировками админки, сайта, базы данных


Вопрос о кодировках в MODx возникает постоянно. Позиция разработчиков и гуру MODx однозначна - необходимо использовать кодировку UTF-8. Об её преимуществах написано немало. У менее опытных пользователей MODx обычно возникает желание использовать кодировку windows-1251. Для этого есть объективные и субъективные причины. Попробуем разобраться, что к чему, а главное - как решать возникающие проблемы.

Под моим контролем находится более двадцати сайтов на одном WEB-сервере. Большинство из них работают под управлением CMS Etomite версий от 0.6.1.2 до 1.1. Там везде используется кодировка windows-1251. Так уж сложилось, хорошо это или плохо.

Все эти сайты вначале разрабатывались на локальном сервере Denwer, инсталлировавшемся из комплекта Base_2006-10-04_a1.3.33_p4.4.3_m4.1.16_pma2.6.1.exe, включающего PHP4.

С Etomite и windows-1251 было всё замечательно. Но значительно позже (как жаль, что не раньше) добрые люди подсказали про MODx. Эта CMS (а вернее CMF) значительно лучше, но происходит от Etomite. При первых испытаниях MODx встал вопрос о кодировках. Переводить-то намечалось существующие сайты, со множеством материалов. И как-то боязно было всё конвертировать.

Это причина субъективная, практически неуважительная. Кроме того задумывался и о трафике. Всё-таки в UTF-8 при русскоязычном контенте трафик раза в полтора больше.

В общем, сначала я, как и многие другие, задумал перевести MODx в кодировку 1251. Сделать это вполне возможно путем настроек и изменения языковых файлов- останавливаться на этом не буду. Собственно, для самой системы управления достаточно выполнить штатные настройки языка в Инструменты-Конфигурация и в config.inc.php и всё будет работать. Но для дополнительных сниппетов и плагинов приходитсяиногда создавать дополнительные языковые файлы в кодировке 1251, а кое-где и влезать в код, чтобы заменить зашитую там кодировку utf-8.

В результате я получил вроде бы работающий сайт на MODx с кодировкой 1251. При этом не работали как надо некоторые сниппеты и плагины и их пришлось заменять на собственные или заимствованные из Etomite. Например AjaxSearch не хотел искать русские слова. Да и известная проблемас отображением некоторых русских символов оставалась.

Окончательный переход на MODx я отложил до выхода анонсированной версии MODx Revolution. Однако разработка Revolution застопорилась на alpha-версиях, а разработчики в конце 2008 года выпустили версию MODx 0.9.6.3. Вот на нее я и решил переехать и добиться полноценной работы.

На локальный сервер MODx 0.9.6.3. я поставил сразу в кодировке UTF-8. Поменяв в демонстрационном сайте часть страниц на русские я сразу убедился, что все известные ранее проблемы отпали.Тексты отображались правильно, превосходно работал AjaxSearch. Все-таки разработчики отлично потрудились, хотя и изменили всего лишь младший разряд в номере версии. Но возникли и проблемы.

Для тестирования сайтов в локальном режиме я использую комплект Denwer, где "всё в одном флаконе". Несколько лет я устанавливал  Denwer  из инсталляционного комплекта Base_2006-10-04_a1.3.33_p4.4.3_m4.1.16_pma2.6.1.exe, включающая PHP4.

Но эта версия оказалась непригодной для работы с MODx 0.9.6.3, так как в ней отстутствовало расширение для работы с мультибайтовыми строками. Это подтолкнуло к давно требовавшемуся решению - переходу на Denwer с PHP5. Поставил его из инсталляции Base_PHP5_2006-10-04_a1.3.33_p5.1.6_m4.1.16_pma2.6.1.exe с комплектом расширений Denwer3_PHP5_2008-01-13_5.2.4.exe. Старые базы данных и сайты просто перенес в новые каталоги.

Перевод на UTF-8 пока предусмотрен для одного сайта (как это сделано напишу ниже). Все остальные остались в кодировке 1251 и работают под Etomite.

В результате замены Denwer все старые сайты в кодировке 1251 перестали правильно отображать информацию из базы данных - вместо русских букв - знаки вопроса!

 

В чем же причина? В конфигурационном файле my.cnf записано:

[client]
port                  = 3306
socket                = /tmp/mysql.sock
default-character-set = cp1251
character-sets-dir    = /usr/local/mysql4/share/charsets
#
# Параметры MySQL-сервера.
#
[mysqld]
# Использовать режим совместимости с клиентами MySQL 3.x и MySQL 4.0.
old-passwords
# Кодировка баз данных по умолчанию.
default-character-set = cp1251
init-connect = "set names cp1251"

Всё вроде бы правильно. В свойствах и баз данных, и таблиц везде указана кодировка cp1251, данные в таблицах просматриваются программой MySQLFront, а вот в браузер выдаются неправильно.

В head страниц прописано

 <meta http-equiv="content-type" content="text/html; charset=Windows-1251" />

 

В таких условиях страницы, возвращаемые MODx, как при кодировке 1251, так и при UTF-8 выглядят нормально, а вот для Etomite - неправильные.

Что в таких условиях можно предпринять для нормальной работы?

Конфигурация WEB-сервера Apache одинаковая, за исключением загрузки разных версий PHP. Конфигурация MySQL в my.conf абсолютно одинаковая. Базы данных имеют правильные опции и кодировки. Версии mysql абсолютно одинаковые. Следовательно - проблема кроется в работе PHP5 с базами данных.

В PHP.INI заремлены

;default_charset = "iso-8859-1"

и одинаковая конфигурация для MySQL. 

В конфигурации MODx в  config.inc.php записаны дополнительные настройки, отсутствующие в ETOMITE:

$database_connection_charset = 'utf8';
$database_connection_method = 'SET NAMES';


При обращении к БД выполняются запросы

mysql_select_db(str_replace('`', '', $dbase));
@mysql_query("{$database_connection_method} {$database_connection_charset}"); 

Второй дополнительный запрос выполняется каждый раз после  mysql_select_db. А вот в Etomite подобного нет! Это и является причиной ошибок. Однако для исправления необходимо влезать в код Etomite. Для локального сервера это сделать достаточно просто, но как это выполнить на хостинге, где имеется куча сайтов с разными версиями движка?

Такие проблемы имеют несколько причин и путей решения. Основная в данном случае - PHP использует неверную кодировку в качестве клиентской. В базе данных кодировка правильная, а клиенту возвращаются вопросы. Решить её можно так:

Решение 1. Сделать, как в MODx - отправкой запроса SET NAMES. Но этого хотелось бы избежать - слишком много кода на разных сайтах придется изменять.

Решение 2.  Заставить MySQL автоматом выполнять этот запрос при каждом коннекте к нему.
Для этого нужно в файле my.cnf иметь строку:

init-connect="SET NAMES cp1251"

 

Такая строка уже есть, но в секции [mysqld], а советуют про [server]. Попробовал сделать - не помогло.

Причина совсем не в секции [server], а в том, что на локальном сервере, для простоты, подключение выполняется от имени пользователя root. Этот пользователь обладает всеми правами и на него этот прием не действует. Но на хостинге нам никто не даст соединяться как root, там всегда для клиентов имеются специальные пользователи.

Пришлось создать дополнительного пользователя с ограниченными правами и на локальном сервере. Записали этого пользователя и его пароль в config.inc.php для всех сайтов, работающих под управлением Etomite и - ура, заработало!

При этом правильно работают и сайты под MODx. Сайты с Etomite не посылают запрос  SET NAMES cp1251, но получают данные именно в этой кодировке автоматически, так как она задана в init-connect="SET NAMES cp1251".

А сайты с MODx сами отправляют запросы  SET NAMES utf8 и для них данные возвращаютс в этой кодировке.

Это пока маленькие беды, так как речь идет о локальном сервере, работающем под Windows. Что будет при переезде на хостинг - совсем другая история.

17-01-2009 00:52:31



    Содержание раздела «О кодировках»:
Комментарии любых посетителей

Написать комментарий