Конвертировать php файлы из windows 1251 в utf 8

Проблема кодировок часто возникает при написании парсеров, чтении данных из xml и CSV файлов. Ниже представлены способы эту проблему решить.

1

windows-1251 в UTF-8

$text = iconv('windows-1251//IGNORE', 'UTF-8//IGNORE', $text);
echo $text;

PHP

$text = mb_convert_encoding($text, 'UTF-8', 'windows-1251');
echo $text;

PHP

2

UTF-8 в windows-1251

$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text);
echo $text;

PHP

$text = mb_convert_encoding($text, 'windows-1251', 'utf-8');
echo $text;

PHP

3

Когда ни что не помогает

$text = iconv('utf-8//IGNORE', 'cp1252//IGNORE', $text);
$text = iconv('cp1251//IGNORE', 'utf-8//IGNORE', $text);
echo $text;

PHP

Иногда доходит до бреда, но работает:

$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text);
$text = iconv('windows-1251//IGNORE', 'utf-8//IGNORE', $text);
echo $text;

PHP

4

File_get_contents / CURL

Бывают случаи когда file_get_contents() или CURL возвращают иероглифы (Алмазные борÑ) – причина тут не в кодировке, а в отсутствии BOM-метки.

$text = file_get_contents('https://example.com');
$text = "\xEF\xBB\xBF" .  $text;
echo $text;

PHP

Ещё бывают случаи, когда file_get_contents() возвращает текст в виде:

�mw�Ƒ0�����&IkAI��f��j4/{�</�&�h�� ��({�񌝷o�����:/��<g���g��(�=�9�Paɭ

Это сжатый текст в GZIP, т.к. функция не отправляет правильные заголовки. Решение проблемы через CURL:

function getcontents($url){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
	$output = curl_exec($ch);
	curl_close($ch);
	return $output;
}

echo getcontents('https://example.com');

PHP

12.01.2017, обновлено 02.11.2021

Другие публикации

Отправка e-mail в кодировке UTF-8 с вложенными файлами и возможные проблемы.

JSON (JavaScript Object Notation) – текстовый формат обмена данными, основанный на JavaScript, который представляет собой набор пар {ключ: значение}. Значение может быть массивом, числом, строкой и…

Описание значений глобального массива $_SERVER с примерами.

Так как Instagram и Fasebook ограничили доступ к API, а фото с открытого аккаунта всё же нужно периодически получать и…

В статье представлены различные PHP-расширения для чтения файлов XLS, XLSX, описаны их плюсы и минусы, а также примеры…

Примеры как зарегистрировать бота в Телеграм, описание и взаимодействие с основными методами API.

Добрый день!

Есть немаленький, старый движок. Чистый код весит около 3 Мб. Около полугода назад успешно перенес его с PHP 5.3 на версию 7.1 — документации по этому делу много. Изучил рекомендации 4-5 хороших статей. И то была пара моментов, которые не были там описаны. В принципе, все прошло достаточно гладко.

Теперь стоит другая задача. Движок настолько старый, что работает с кодировкой Windows-1251. Нужно переделать все под UTF-8. Сколько не искал — ничего толкового из советов не нашел. Большинство хорошей инфы идет из-за бугра, а для них Win-1251 не актуальна. :)

По сути единственное, что опишут — это заменить все функции работы со строками на их «mb_» аналоги. Я так понимаю, речь идет об этом списке аналогов: php.net/manual/ru/ref.mbstring.php ?

Насколько я понимаю, по части PHP нужно будет еще как минимум задать нужную кодировку в конфиге. Перекодировать сами PHP файлы в UTF-8. БД — то уже отдельные пляски. Еще из нюансов — на сайте есть AJAX, с перекодировкой результатов (т.к. такие запросы, если не ошибаюсь, отправляются только в UTF-8).

Все, этого достаточно? Что еще может быть, у кого есть опыт в подобном деле? И самое главное — нельзя ли просто в настройках PHP указать что «работаем с UTF-8» и точка. Чтобы не менять все функции?

Да и по самим функциям непоняточки. Например, есть preg_replace, но нет mb_preg_replace. Хотя в то же время есть и ereg_replace, и в то же время mb_ereg_replace. Хоть ereg_replace уже устаревшая / удаленная (в зависимости от версии PHP) функция. Как это понимать?

Запутался в конец.

2019.03.07 обновляю: узнал за эти дни много нового и интересного. :) думаю, многие очень поверхностно относятся к пониманию кодировок. Не знаю, актуальна ли тема на 2019 год. Но если что, в принципе, после всего этого могу сделать большой чек-лист что и как надо делать. Третий день переделываю движок под UTF-8. Реально исправлять код действительно не во многих местах надо. Но точек проверок очень много.

А теперь маленький вопрос-уточнение к знающим людям. Везде про preg_* функции пишут в стиле «используйте модификатор u чтобы работать с юникодом». А когда он реально необходим? По моим наблюдениям, функциям все равно со строками в каких кодировках работать. В PHP отношение ко строкам как к набору байт, а не символов. И походу модификатор u необходимо использовать только когда само регулярное выражение содержит символы за пределами US-ASCII. В противном случае любые UTF-8 строки корректно обрабатываются без модификатора u. Что скажите?

Имеется сайт на PHP, существующий уже много-много лет. Сайт создавался и развивался в кодировке windows-1251, но дальше так жить невозможно, надо весь PHP-код преобразовать в UTF-8, то же самое сделать с html-, css-, js- и прочими файлами, сконвертировать базу данных MySQL и ещё кое-что подправить.

Как быстро выполнить переход сайта на кодировку UTF-8?

Нам помогут знания из статьи про recode и enconv, добавим к ним ещё кое-что.

Все действия можно свести в один bash-скрипт, отдельные части которого рассмотрим в статье.

1. Создать копию всех файлов сайта. Например, сайт находится в /var/www/site. Для работы сайта ещё используются /var/www/dir1, /var/www/dir2, /var/www/dir3, причём dir1 и dir2 надо перекодировать вместе с site, а dir3 не надо трогать. Скопируем всё в /var/www-u8. Для удобства будем использовать переменные, в которых сохраним часто используемые строки.

dir_source=’/var/www’

dir_u8=’/var/www-u8′

cp -R ${dir_source}/* ${dir_u8}

Массив, содержащий имена подкаталогов, в которых надо обработать файлы:

subdirs=(site dir1 dir2)

Во всех подкаталогах надо перекодировать из windows-1251 в UTF-8 все файлы с расширениями: php, txt, js, css, htm. Нам поможет enconv. Затем найти подстроки «windows-1251» или «cp1251» и заменить на «UTF-8». Наконец, найти в php-файлах короткий открывающий тег «<?» и заменить его на полный «<?php». Регулярное выражение для поиска короткого тега ищет строку ‘<?’, после которой следует пробел, конец строки или символ ‘=’ (для файлов, в которых php-код используется вперемешку с html для вставки значений переменных: ‘<?=$var;?>’). Все замены поможет выполнить могучий sed, а с подбором файлов для обработки отлично справится find. Поскольку обработку надо выполнить в нескольких подкаталогах (их имена хранятся в массиве $subdirs), то перебираем элементы массива в цикле (подробнее про использование массивов в bash) и из них составляем путь для поиска командой find.

for item in ${subdirs[*]}
do
  sPath=${dir_u8}/${item}
  find ${sPath} -iregex '.*\.\(txt\|php\|css\|js\|html?\)' -exec enconv -L russian -x utf8/LF '{}' \;
  find ${sPath} -iregex '.*\.\(txt\|php\|css\|js\|html?\)' -exec sed -i -r 's/windows-1251|cp1251/UTF-8/ig' '{}' \;
  find ${sPath} -iname '*\.php' -exec sed -i -r 's/(<\?)(\s|$|=)/<?php\2/ig' '{}' \;
done

С перекодировкой базы данных MySQL вообще всё просто. Надо сделать дамп данных, в области описания таблиц заменить строки, определяющие кодировку, загрузить дамп в новую в базу. Примерно так:

HOST_1='localhost'
USER_1='user1'
PASSWORD_1='password1'
DATABASE_1='database1'

HOST_2='localhost'
USER_2='user2'
PASSWORD_2='password2'
DATABASE_2='database2'

DUMPFILE_1="db-${DATABASE_1}.sql"
DUMPFILE_2="db-${DATABASE_2}.sql"

# dump from the original DB
mysqldump -u ${USER_1} -h ${HOST_1} -p${PASSWORD_1} --opt ${DATABASE_1} > ${DUMPFILE_1}

# Replace charset settings from cp1251 to utf8
sed -r 's/CHARSET=cp1251/CHARSET=utf8/ig' ${DUMPFILE_1} > ${DUMPFILE_2}

# Load data from the dump
mysql -u ${USER_2} -h ${HOST_2} -p${PASSWORD_2} ${DATABASE_2} < ${DUMPFILE_2}

В скрипте все переменные, имена которых оканчиваются на «1», относятся к исходной базе данных, работающей в кодировке cp1251. Все переменные, имена которых оканчиваются на «2», относятся к новой базе данных, которая будет использоваться в перекодированном в utf-8 сайте.

Осталось установить для файлов в ${dir_u8} нужные права доступа, при необходимости настроить контекст безопасности SELinux и, наконец, настроить вебсервер для визуальной проверки перекодированного сайта.

Если свести воедино все фрагменты bash-скрипта, написанные на этой странице, то, фактически, весь процесс изменения кодировки сайта на utf-8 окажется простым и быстрым.

If you need convert string from Windows-1251 to 866. Some characters of 1251 haven't representation on DOS 866. For example, long dash -- chr(150) will be converted to 0, after that iconv finish his work and other charactes will be skiped. Problem characters range in win1251 (128-159,163,165-167,169,171-174,177-182,187-190).

Use this:

//$text - input text in windows-1251
//$cout - output text in 866 (cp866, dos ru ascii)

for($i=0;$i<strlen($text);$i++) {
$ord=ord($text[$i]);
if($ord>=192&&$ord<=239) $cout.=chr($ord-64);
elseif($ord>=240&&$ord<=255) $cout.=chr($ord-16);
elseif($ord==168) $cout.=chr(240);
elseif($ord==184) $cout.=chr(241);
elseif($ord==185) $cout.=chr(252);
elseif($ord==150||$ord==151) $cout.=chr(45);
elseif($ord==147||$ord==148||$ord==171||$ord==187) $cout.=chr(34);
elseif($ord>=128&&$ord<=190) $i=$i; //нет представления данному символу
else $cout.=chr($ord);
}

13 Nov 2016 | Автор: dd |

Перевозил тут пачку сайтов с LAMP на LNAMP, где фронтэндом выступает NGINX. И все бы ничего, если бы не пачка статических сателлитов в кодировке Windows-1251 (cp1251).

Как тут прикололся девака – при анализе сайта, надо сначала чекать кодировку и в случае обнаружения кодировки сайта cp1251 – проверку возраста можно не осуществлять. Но, тем не менее, в инетах до сих пор встречаются такие мастадонты, которые клепают сайты в кодировке CP1251.

Под апачем, при добавлении сайта в ISP Panel это даже не заметишь, а вот при попытке добавить этот же сайт в Vesta CP, получаешь гемор на задницу с крикозябрами. Поэтому надо редактировать конфиг Nginx, предварительно прикрутив туда виндовую кодировку. Но, насколько я помню, у меня этот танец с бубнами не задался и в тот раз, я просто повесил саты на LAMP.

Так что оставалось либо плясать с бубнами вокруг прикручивания виндовой кодировки к NGINX, либо перекодивать файлы в родную для нжинкса UTF-8. Сделать это можно средствами текстового редактора Notepad++ путем перевода кодировки документа и последующего сохранения; либо же в самом линухе.  Как я выше заметил, саты статические, то есть на файлах, без использования базы данных. Поэтому перекодировать надо было именно файлы. С базой данных все происходило бы несколько иначе.

Перекодировка файла из CP1251 в UTF-8 производится в консоли через команду iconv
# iconv -f cp1251 -t utf8 FILE-CP1251 -o FILE-UTF8
либо же можно переписать файл в самого себя
# iconv -f cp1251 -t utf8 file.txt -o file.txt

Но поскольку мне надо было перекодировать большое число файлов php, содержащихся в разных папках, то мне пришлось составить  небольшое предложение:
# find /path-to-files/ -type f -name \*php -exec iconv -f cp1251 -t utf-8 '{}' -o '{}' \;

Конвертит все в лет.

Для конвертации кодировок есть еще утилита enconv, входящая в состав пакета enca – вот он как раз конвертит сам в себя по умолчанию, перезаписывая файл выходной кодировкой:
# enconv -c file.txt

но, к сожалению, я его не смог подружить с русским языком, т.к даже при указании языка через ключик -L russian скрипт матерился на ошибки. Но с другой стороны, все нормально решилось и через iconv

Rating: 4.4/10 (23 votes cast)

Rating: +1 (from 3 votes)

Смена кодировки сайта из CP1251 на UTF-8, 4.4 out of 10 based on 23 ratings

Теги: centos, сайты

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Как установить windows 10 на steam deck
  • Как сделать свой экран загрузки windows 10
  • Какие временные файлы можно удалить в windows 10
  • Сертификат фстэк microsoft windows
  • Почему не входит в учетную запись windows 10