Після переходу з MySQL 4 на MySQL 5 я зіткнувся з некоректним відображенням кирилиці у старому PHP-сайті. У 2007 році цей сайт працював із Windows-1251, тому важливо було простежити кодування на всьому шляху: від бази даних до браузера.
Три різні рівні кодування
Потрібно узгодити фактичне кодування даних у базі, кодування з’єднання клієнта із сервером і кодування HTTP-відповіді. Сам перехід на MySQL 5 не означав, що всі бази автоматично ставали UTF-8: параметри задаються на різних рівнях сервера, бази, таблиці й стовпця.
SET NAMES 'cp1251' за документацією MySQL повідомляє серверу, в якому кодуванні клієнт надсилає запити та очікує результати. Команда не є універсальним перетворювачем неправильно збережених даних. Значення слід обирати відповідно до реального кодування застосунку.
Приклади з початкового допису
У phpNuke я додавав запит після підключення до бази у файлі mainfile.php. Також вказував кодування на початку дампа під час перенесення між серверами. У тодішній конфігурації Apache2 використовував файл /etc/apache2/conf.d/charset; розташування конфігурації в інших інсталяціях може відрізнятися.
Код нижче збережено як історичний матеріал. У ньому є помилки й застарілий синтаксис, тож це не готовий сценарій міграції:
// Rudjuk 24.06.2007 Change Error Code
if ($db){
$db->sql_query("set names 'cp1251'");
}
SET NAMES CP1251
< meta http-equiv="content-type" content="text/html; charset=windows-1251" />
AddDefaultCharset windows-1251
SHOW VARIABLES LIKE 'character_set_client';
CREATE DATABASE `inv2_neru` CHARACTER SET cp1251 COLLATE cp1251_bin COLLATE cp1251_bin;
^
CREATE TABLE `ibf_admin_login_logs` (
`admin_id` int(10) NOT NULL auto_increment,
`admin_ip_address` varchar(16) NOT NULL default '0.0.0.0',
`admin_username` varchar(40) NOT NULL default '',
`admin_time` int(10) unsigned NOT NULL default '0',
`admin_success` int(1) unsigned NOT NULL default '0',
`admin_post_details` text,
PRIMARY KEY (`admin_id`),
KEY `admin_ip_address` (`admin_ip_address`),
KEY `admin_time` (`admin_time`)
) TYPE=MyISAM AUTO_INCREMENT=84 CHARACTER SET cp1251 COLLATE cp1251_bin;
^Що потрібно виправити перед використанням
- У рядку CREATE DATABASE двічі повторено COLLATE; має бути одна відповідна умова.
- Запис
< metaмістить зайвий пробіл після кутової дужки. - Роздільники
^не є самостійними SQL-командами. - Старий приклад із
TYPE=MyISAMтреба перевіряти за синтаксисом цільової версії; механічно переносити весь DDL не можна.
Директива Apache AddDefaultCharset задає параметр charset для відповідей text/plain і text/html. Вона не перекодовує самі байти; за документацією Apache її слід застосовувати лише до ресурсів із відомим однаковим кодуванням. Глобальна заміна на Windows-1251 може зіпсувати відображення інших сторінок.
Перед міграцією збережіть копію бази та перевірте шлях даних на тестовому середовищі. У MySQL 8.0 підтримується utf8mb4, але перехід до нього потребує коректного перетворення фактичних даних і налаштування клієнта.
Немає коментарів:
Дописати коментар