Кирилица в MySQL – Решаване на проблеми с кодировката

Вероятно няма уебмастър в България, койото поне веднъж да не е успял да превърне съдържанието на база данни във въпросителни знаци при експорт / импорт на бакъп дъмп файл с phpmyadmin или през shell. Ето няколко насоки за mysql енкодинг (информацията е базирана на mysql сървър 4.1+ и PhpMyAdmin 2.6.4+).

Термини

Енкодинг (encoding, character encoding), чарсет (charset, character set) - Тези понятия описван начина по който се съхраняват символите във вид на някакъв цифров код. Примери за енкодинги са windows-1251 (в mysql е cp1251), utf-8 (в mysql е utf8), ISO-8859-1 кодировка и т.н.

Колация (collation) - Това е начина по който се интерпретира енкодинга. За всеки енкодинг може да има няколко колации и ако сортирате текстовите полета от някоя mysql таблица с различни колации, вероятно ще се подредят по различен начин. Една колация може да работи с един енкодинг само. В mysql не е нужно да задавате изрично колацията. Когато зададете енкодинг cp1251 примерно, mysql ще използва по подразбиране cp1251_general_ci collation (това важи за таблици, конекции и т.н.).

Първоначално създаване на база данни

При създаване на база данни, в която ще има текст на кирилица, най-добре е да се използва същия енкодинг (и колация), какъвто използва и самия сайт при показване в браузъра. По-новите CMS системи като Joomla, Drupal, WordPress използват utf8. Ако не бъде изрично зададен character set, ще се използва този, който е по подразбиране в съответния mysql сървър.

Mysql 4.1 и по-новите версии поддържат възможността да се зададе различен енкодинг и колация за всяка таблица или поле. Тези настройки можете лесно да променяте с PhpMyAdmin. Ако сменяте енкодинга на таблица или поле, трябва да се внимава да не се преминава към енкодинг, който липсват някои от символите в оригиналния енкодинг.

Изпълнение на заявки към база данни с кирилица

Правилно е да изберете един енкодинг за всички компоненти на вашия сайт. Например, ако изберете windows-1251 (cp1251), трябва или в http хедъра или с мета таг да укажете това за вашите php, cgi, aspx или други файлове. Освен това самия файл е необходимо да се запази със съответната кодировка. Някои от текстовите редактори поддържат възможност за избор на кодировка в която да се запази вашия код.

Следващата стъпка е да настроите вашето приложение и mysql да обменят данни в един и същ енкодинг. Обикновено причината да не се показва нормално кирилицата на вашия сайт е именно заради факта, че двете си говорят на различни езици. В конфигурационния файл на mysql е правилно да се зададе какъв да бъде encoding по подразбиране за всички конекции към сървъра:

character-set-server = utf8
init_connect = 'SET NAMES utf8'

Вероятно обаче няма да имате възможност да редактирате конфигурацията на mysql сървъра ако ползвате споделен хостинг. Какво ще стане ако на сървъра енкодинг по подразбиране е cp1251, а вашата база данни е с utf8 и вашите php файлове са съответно utf-8? На пръв поглед нищо няма да стане и ще работи (за съжаление)! Самите данни в базата ще се съхраняват в напълно грешен вид и проблема ще се появи едва когато се опитате да преместите базата данни на друг хостинг сървър (примерно собствен VPS хостинг) или се опитате да я възстановите от backup. За да избегнете подобни проблеми, винаги изрично уведомявайте mysql какъв енкодинг да използва по време на всяка конекция (connection):

$link = mysql_connect('host', 'user', 'password');
mysql_query('set names utf8', $link);

По този начин, дори на сървъра character set по подразбиране да е cp1251, данните към и от сървъра за вашето php приложение ще се обменят в utf8 encoding.

Експорт и импорт на база данни

За експортиране на база данни можете да ползвате phpmyadmin или mysqldump, които ще генерират тескотов файл (dump), със структурата и данните на вашата база. При големи бази данни е препоръчително да ползвате mysqldump (необходим ви е ssh достъп до сървъра).

По подразбиране и двете програми ще генерират дъмп в utf-8 формат независимо с какъв чарсет е базата. Това е нормално и не е проблем. Енкодинга на файла е utf-8, но ако в базата таблиците са били с cp1251, това ще бъде отбелязано в sql кода за създаване на таблицата в самия дъмп файл.

/*!40101 SET NAMES utf8 */;
CREATE TABLE `mytable` (
`my_id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`my_text` VARCHAR(100) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

Това е дъмп създаден от mysqldump. Файлът е в unicode формат и това е отбелязано в самото начало. Така при импортиране на този файл след това mysql ще интерпретира символите правилно. Когато mysql види, че трябва да създаде таблицата в cp1251 чарсет и колация, той автоматично ще преведе чарсета от utf към cp1251. PhpMyAdmin ще направи подобен dump, но за съжаление ще пропусне 'SET NAMES' указанието. Това може да доведе до проблем, при импорт и е добре да го добавите.

Ако не сте сигурни какъв точно е файловия енкодинг на вашия дъмп, можете да проверите по следния начин - дъмпа се отваря в Firefox (или друг браузър) и от View → Character Encoding се сменя докато кирилицата стане читаема. Запомня се при какъв чарсет се чете и това се записва в реда /*!40101 SET NAMES utf8 */;. Не забравяйте, че когато в браузъра е utf-8, трябва в дъмп файла да го запишете utf8, а windows-1251 като cp1251. Също така може да се ползва опцията за чарсет при ъплоуд в phpmyadmin.

Когато е направен дъмп на база данни съхранявана в неправилен енкодинг, обикновено се поврежда кирилицата. Почти винаги проблема може да се оправи. Свържете се с нас и ще ви помогнем!

happy coding :)

------
Информацията в този tutorial е валидна само за версии на MySQL Database Server 4.1 +. Ако не сте намерили разрешение на вашия проблем в статията или имате предложения за подобрения, моля пишете ни и ще се постараем да я обогатим.
При публикуване на извадки от текста, моля поставете линк към тази статия.

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *