Miramar ReservoirMiramar Reservoir // 2016-07-30

WordPress та кодування

Оскільки в мене з’явилося трохи вільного часу — я почав переписувати свою домашню сторінку.
Що потрібно зробити:

  • новий двигунець — зараз фактично є набір скриптів, що мало пов’язані між собою
  • англомовна версія — хоча б інформація про мене та резюме
  • новий дизайн — є декілька ідей, але вони ще на стадії створення макету
  • XHTML 1.0 Strict та utf8 — зараз це є лише в блозі
  • AJAX в галереї та скриптах — потрібно не відставати від прогресу
  • та багато іншого…

Почав я з 4-го пункту, а саме з перекодування бази в utf8.
Там знаходяться таблиці WordPress’у, галереї, подкасту і т.п.

Таблиці галереї були в cp1251, тому перекодування їх в utf8 пройшло без проблем.
В скрипті галереї я додав лише один рядок (оскільки вона і досі генерує сторінки в cp1251, це зміниться лише після переходу на новий двигунець).
mysql_query("SET NAMES 'cp1251';", $link);

Таблиці подкасту я створював відносно недавно, тому вони вже були в utf8

Таблиці WordPress’у на перший погляд були в cp1251, але спроба поміняти кодування закінчилася невдало — кириличний текст став таким: неопубліковане

Після ґуґління™ я знайшов причину цих глюків.
Раніше (ще 2-3 роки тому) MySQL по замовчуванню налаштовували на cp1251 (якщо це вітчизняний хостинг) або latin1 (якщо зарубіжний). А WordPress взаємодіє з базою в кодуванні utf8 навіть якщо база має зовсім інше кодування.
Тому блоґер спокійно веде свій блоґ навіть не знаючи, які проблеми у нього виникнуть в майбутньому

А ці проблеми рано чи пізно з’являться — після переходу на інший хостинг або після оновлення ПО на поточному. Новий MySQL по замовчуванню починає використовувати utf8 і в блозі збивається кодування.
Це можна тимчасово виправити за допомогою таких рядків в wp-config.php
define('DB_CHARSET', 'cp1251');
define('DB_COLLATE', 'cp1251_general_ci');

Фактично це повернення статусу-кво — для MySQL кодування бази є cp1251 а WordPress взаємодіє з нею в кодуванні utf8.

В такому вигляді мій блоґ міг жити і далі, але я люблю порядок в усьому
Що потрібно зробити — змінити кодування бази (cp1251 -> utf8), при цьому не перекодовуючи базу (оскільки текст в ній вже є в utf8).

Ну а що ж тут важкого? Беремо дамп бази в phpmyadmin, відкриваємо його в текстовому редакторі як файл в кодуванні utf8 і скрізь міняємо
DEFAULT CHARSET=cp1251
на
DEFAULT CHARSET=utf8
Але проблема тут в тому, що phpmyadmin бачить, що база в нас в cp1251, тому при експорті автоматично перекодовує її cp1251 -> utf8 (а цього нам якраз і не треба, оскільки база і так вже в utf8).

Є інших спосіб — потрібно змінити тип усіх текстових полів таблиці (CHAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT) на їх бінарні аналоги (BINARY, VARBINARY, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB), потім змінити кодування таблиці на utf8 а потім поміняти тип полів назад на текстові.
Лінк в тему — Перенесення WordPress блогу на інший хостинг
Таблиць у нас 10-15 (залежно від встановлених плагінів) тому це не шлях справжніх самураїв ІТ’шників

Я знайшов швидший спосіб, але він потребує доступу до хостингу по ssh.
Експортуємо базу в тому вигляді, в якому вона є
mysqldump -u користувач --password=пароль --opt --default-character-set=cp1251 --skip-set-charset -Q база > dump.sql
Завантажуємо дамп собі на комп’ютер, відкриваємо його як файл в кодуванні utf8, скрізь міняємо
DEFAULT CHARSET=cp1251
на
DEFAULT CHARSET=utf8
і зберігаємо (теж як utf8, бажано без BOM).
Далі створюємо нову базу (вже в кодуванні utf8) та імпортуємо туди цей файл.
Потім модифікуємо wp-config.php (змінюємо базу зі старої на нову) і, для повної гарантії, додаємо такі рядки:
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', 'utf8_general_ci');

Все, можна спокійно писати в блоґ