Кодировочный Ад или боремся с windows-1251

Написано 28 Ноябрь, 2012 в категории MySQL

Наличие большого количества несовместимых кодировок всегда было огромной головной болью разработчиков. Думаю каждый может вспомнить часы проведенные над преобразованием одной кодировки в другую пока не появятся заветные родные символы. Очень приятно, что все реже и реже встречаются koi8r и cp1251, но если встречаются - наберитесь терпения, оно вам точно пригодится!

Однажды, разворачивая у себя очередной самопальный сайт, вновь повстречался с cp1251. Сайт делали на стыке тысячелетий, так что понять можно. Со временем сайт разрастался, люди его поддерживающие менялись, не менялось только одно - кодировка! Естественно как приверженец utf8 я получил на страницах сайта вместо кириллицы набор вопросительных знаков.

На чем я запускал сайт:

ОС

> lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 12.04.1 LTS
Release:	12.04
Codename:	precise

mysql(на стандартный mysql я наложил mariadb, но думаю для данного случая это не принципиально)

mysql> select version();
+-------------------------------------+
| version()                           |
+-------------------------------------+
| 5.5.28-MariaDB-mariadb1~precise-log |
+-------------------------------------+

Apache2

> apache2 -v
Server version: Apache/2.2.22 (Ubuntu)
Server built:   Nov  8 2012 21:37:30

Сайи: Исходники сайта в cp1251, все таблицы БД в cp1251.

Текст на страницах сайта выводится как правило 2мя способами:
1. просто забивается в php или html файл или какой-либо другой файл.
2. подгружается из БД.
При этом может возникать ситуация, когда часть текста отображается правильно, а часть крякозябрами. Это означает одно - либо неверно декодируется текст из пункта 1, либо из пункта 2.

Как должны быть сконфигурированы apache2 и mysql для корректного отображения кириллицы на сайте?

1. У меня были исходники в cp1251, значит кодировка которую устанавливает apache2 для страниц сайта должна быть cp1251. Чтобы проверить с какой кодировкой apache возвращает страницы я использую плагин в Google Chrome - HTTP Headers (https://chrome.google.com/webstore/detail/http-headers/hplfkkmefamockhligfdcfgfnbcdddbg). Http-заголовок должен содержать вот такую строку: Content-Type text/html; charset=windows-1251
Благодаря этой строчке браузеры определяют в какой кодировке отображать страницы сайта. Иногда это автоматическое определение сбивается, поэтому если что-то не в порядке с кодировкой убедитесь, что браузер определил её правильно (Для Google Chrome кликаем по иконке гаечного ключа в правом верхнем углу окна, выбираем Инструменты->Кодировка и устанавливаем Кириллица (Windows-1251)).
Если apache возвращает сайт в другой кодировке, например, так: text/html; charset=UTF-8, необходимо указать apache2 что должна быть кодировка именно windows-1251. Для этого служит директива: AddDefaultCharset windows-1251, её можно разместить в настройках виртуального хоста или в .htaccess. Мне с этим повезло, т.е. мне достался готовый файл .htaccess с уже прописанной директивой.

2. Второй источник головной боли - это БД. У меня mysql настроен на использование utf-8. Mysql файл с базой в кодировке cp1251, все таблицы в cp1251. К сожалению к скрипту не прилагалась команда создания БД, поэтому мне пришлось прописывать её принадлежность к cp1251 вручную:

 CREATE DATABASE `mydb` CHARACTER SET cp1251 COLLATE cp1251_general_ci;

C помощью mysql-команды source я загрузил в созданную БД таблицы с данными. На сайте кириллица отобразилась правильно, а вот в консоли она по-прежнему отображалась в виде вопросительных знаков.
Чтобы все отображалось как надо достаточно в консоли выполнить: set names utf8;.

Удачи в борьбе за utf8! Перевести сайт на utf8 значительно проще, чем кажется. Если нужна помощь - обращайтесь.