Борьба с кодировками

После переноса одного из сайтов работающих на ModX CMS с одного сервера на другой, возникла проблемма с работой галереи, при попытки увеличить изображение выдавалась ошибка.

Image cannot be loaded. Make sure the path is correct and image exist.

При проверке было обноруженно что многие имена файлов отображаются не так как должны. Проблема была связанна с тем что файлы имели имена на кирилице, в результате чего имена файлов после переноса приобрели вид:

СÑенка ÐаниÑÐ»Ñ 3600Ñ 2100Ñ 500 ÐÐСРÑзкий ÑÑапик комбиниÑованнаÑ

С помошью онлайн декодера

Удавалась расшифровать в что то вроде:

С�енка �ани�л� 3600� 2100� 500 ��С� �зкий ��апик комбини�ованна�

А также получили подсказку:

Как нам пришлось помучиться
ISO-8859-1 → UTF-8

Говорящюю о том что кодировка старого сервера была ISO-8859-1 а нового UTF-8.

В ручную переименовывать файлы было бы не логичным.

В базе данных у нас имелись нормальные имена файлов и id галерей от которых зависил путь.

Был выбран примерно следуший алгоритм решения.

Для начала папка /assets/galleries/ была скопированна в папку /assets/galleries2/

Из таблици были выбраны все записи, для каждого изображения брался путь к галлереии.

В галлереи производился обход всех файлов и декодирования их имен из ISO-8859-1 в UTF-8 если декодированное имя файла совпоадает с именем файла в базе то файл копировался в новую папку галереи, так как для каждого изображения создовались ещё и превью а также хранились оригиналы приходилось копировать и их.

Весь скрипт на php выглядит так.

<?php
	error_reporting(E_ALL);
	$database_type = 'mysql';
	$database_server = 'localhost';
	$database_user = 'user';
	$database_password = '123';

	mysql_connect($database_server, $database_user, $database_password);
	mysql_select_db('db');
	mysql_set_charset('utf8');

	$result = mysql_query("SELECT * FROM `modx_portfolio_galleries`");

	while ($row = mysql_fetch_object($result)) {
		$dir = './assets/galleries/' . $row->content_id;
		if ($dh = opendir($dir)) {
			while (($file = readdir($dh)) !== false) {
				if ($file != '.' and $file != '..' and $file != 'original' and $file != 'thumbs') {
					$old_file = mb_convert_encoding ( $file, 'ISO-8859-1', 'UTF-8' );
					if ($old_file == $row->filename) {
						copy("./assets/galleries/$row->content_id/$file",
							"./assets/galleries2/$row->content_id/$row->filename");
						copy("./assets/galleries/$row->content_id/original/$file",
							"./assets/galleries2/$row->content_id/original/$row->filename");
						copy("./assets/galleries/$row->content_id/thumbs/$file",
							"./assets/galleries2/$row->content_id/thumbs/$row->filename");
					}
				}
			}
			closedir($dh);
		}
	}
?>

После выполнения скрпита папка galleries была удалена а galleries2 переименованна в galleries.

Можно было бы обоитись без сраврнения имён файлов с имеющимися в базе.

Просто рекурсивно обойти все каталоги и сделать переименовывание всех файлов из имени в кодировке ISO-8859-1 в имя преобразованное в кодировку UTF-8 но в этом случае могли бы возникнуть проблемы с вновь созданными файлами, однако этого было бы избежать проверяя дату изменения файла.

PHP, UTF-8, ISO-8859-1, Кодировки, Encoding, Кирилица, ModX
View: 8961