- Перекодировка текста UTF-8 и WINDOWS-1251
- windows-1251 в UTF-8
- UTF-8 в windows-1251
- Когда ни что не помогает
- File_get_contents / CURL
- Решение проблем неправильной кодировкой веб-страницы
- Неправильная кодировка HTML страниц
- Тестовый файл для проверки кодировки
- Тестовый файл для проверки кодировки
- Как установить UTF-8 кодировку в PHP
- Неправильная кодировка результатов из базы данных MySQL
- Изменение кодировки файлов
- Как узнать, какую кодировку отправляет сервер
- Какую кодировку выбрать для веб-сайта
- Связанные статьи:
- Рекомендуемые статьи:
- 4 Комментарии
- ??rg d�y�?l?r
Перекодировка текста UTF-8 и WINDOWS-1251
Проблема кодировок часто возникает при написании парсеров, чтении данных из xml и CSV файлов. Ниже представлены способы эту проблему решить.
windows-1251 в UTF-8
$text = iconv('windows-1251//IGNORE', 'UTF-8//IGNORE', $text); echo $text;
$text = mb_convert_encoding($text, 'UTF-8', 'windows-1251'); echo $text;
UTF-8 в windows-1251
$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text); echo $text;
$text = mb_convert_encoding($text, 'windows-1251', 'utf-8'); echo $text;
Когда ни что не помогает
$text = iconv('utf-8//IGNORE', 'cp1252//IGNORE', $text); $text = iconv('cp1251//IGNORE', 'utf-8//IGNORE', $text); echo $text;
Иногда доходит до бреда, но работает:
$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text); $text = iconv('windows-1251//IGNORE', 'utf-8//IGNORE', $text); echo $text;
File_get_contents / CURL
Бывают случаи когда file_get_contents() или CURL возвращают иероглифы (ÐлмазнÑе боÑÑ) – причина тут не в кодировке, а в отсутствии BOM-метки.
$text = file_get_contents('https://example.com'); $text = "\xEF\xBB\xBF" . $text; echo $text;
Ещё бывают случаи, когда file_get_contents() возвращает текст в виде:
Это сжатый текст в 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');
Решение проблем неправильной кодировкой веб-страницы
При неправильной кодировке весь сайт или его часть отображаются в виде «кряпозяблов», т.е. непонятных символов, делающих текст нечитаемым. Такая ситуация может возникнуть при неверной настройке кодировки веб-сервера или при отсутствии настроек. Рассмотрим возможные варианты и способы устранения проблем
Неправильная кодировка HTML страниц
sudo gedit /var/www/html/encoding.html
Скопируем в него следующий HTML код, в котором отсутствует указание кодировки и посмотрим, какие проблемы могут с ним возникнуть и как их решить:
Тестовый файл для проверки кодировки
Как можно видеть, кодировка браузером определена неправильно:
Имеется несколько способов исправить эту ситуацию. Начнём с самого простого – явно указать кодировку для веб-страницы. Это делается метатегом, который должен быть расположен внутри тэга head:
Добавим эту строку к нашему тестовому файлику, чтобы получилось так:
Тестовый файл для проверки кодировки
Как мы можем убедиться на следующем скриншоте, проблема решена:
Если кодировка вашего файла отличается от UTF-8, то вместо неё поставьте windows-1251 или ту, которая соответствует кодировке веб-страницы. Чтобы научиться определять кодировку файлов, посмотрите эту инструкцию.
Это был самый простой способ исправления проблемы с кодировкой – без изменения настроек сервера.
Вернём наш тестовый файл в исходное состояние и продолжим изучение способов указания кодировки.
Если файлы .htaccess включены настройками Apache, то эти файлы можно использовать чтобы указывать кодировку отправляемых веб-сервером страниц. Чтобы включить поддержку файлов .htaccess в конфигурационном файле Apache ( /etc/apache2/apache2.conf ) найдите группу строк
Options Indexes FollowSymLinks AllowOverride None Require all granted
После этого сервер нужно перезапустить.
sudo systemctl restart apache2.service
Файл .htaccess должен быть размещён в той же директории, что и сайт. Мой сайт размещён в корневой директории веб-сервера. Если у вас также, то теперь в папке /var/www/html/ создайте файл .htaccess и добавьте в него директиву AddDefaultCharset после которой укажите желаемую кодировку. Примеры
AddDefaultCharset windows-1251
Можно указать кодировку, которая будет применена только к файлам определённого формата:
AddCharset utf-8 .atom .css .js .json .rss .vtt .xml
Набор файлов может быть любым, например:
AddCharset utf-8 .html .css .php .txt .js
Следующий вариант является альтернативным и также позволяет устанавливать кодировку для файлов определённого типа, для него нужно, чтобы был включён mod_headers:
Header set Content-Type "text/html; charset=utf-8"
Ещё один вариант, который также можно использовать в файле .htaccess для установки кодировки UTF-8:
Если сайт на PHP, то дополнительно может понадобиться продублировать кодировку с php_value default_charset:
AddDefaultCharset windows-1251 php_value default_charset "cp1251"
Можно вместо создания файла .htaccess установить кодировку в конфигурационном файле веб-сервера. Для Apache CentOS/Fedora это файл httpd.conf, а на Debian/Ubuntu это файл apache2.conf. Добавьте следующую строку для установки кодировки и перезапустите веб-сервер, чтобы изменения вступили в силу:
Как установить UTF-8 кодировку в PHP
В PHP скрипте для установки кодировки используется header, например:
header('Content-Type: charset=utf-8');
Обычно вместе с кодировкой также указывают тип содержимого (в примере вариант для HTML страницы):
header('Content-Type: text/html; charset=utf-8');
Ещё один вариант для RSS ленты:
header('Content-type: text/xml; charset=utf-8');
Помните, что функция header должна быть вызвана перед любым выводом в браузер. В противном случае (если вывод в браузер уже был сделан), то уже были отправлены и заголовки. Очевидно, что в этом случае их уже невозможно поменять. Если в браузер было выведено сообщение об ошибке, то заголовки также уже были отправлены и использование header вызовет ошибку. Для проверки, были ли уже отправлены заголовки, используйте headers_sent.
Описанный способ работает только когда PHP скрипт полностью генерирует содержимое страницы. Статические страницы (такие как html) вы должны сохранять в кодировке utf-8. Большинство веб серверов обратят внимание на кодировку файла и добавят соответствующий заголовок. На самом деле, сохранение PHP файла в кодировке utf-8 приведёт к такому же результату.
Неправильная кодировка результатов из базы данных MySQL
Если ваш сайт состоит из статической части (шаблон) и динамической, которая формируется из данных, получаемых из базы данных, то может возникнуть ситуация, когда часть сайта имеет правильную кодировку, а другая часть сайта имеет неправильную. В этом случае бесполезно менять настройки веб-сервера – поскольку всё равно часть страницы будет иметь неправильную кодировку.
Нужно начать с определения кодировки ваших таблиц. Можно посмотреть в phpMyAdmin:
Обратите внимание на столбец «Сравнение», запись «utf8_unicode_ci» означает, что используется кодировка UTF-8.
Можно подключиться к СУБД MySQL и проверить кодировку таблиц без phpMyAdmin. Для этого:
Если вы забыли имя базы данных, то выполните команду:
Предположим, я хочу посмотреть кодировку для таблиц в базе данных information_schema
Если вы забыли имя таблиц, выполните:
Далее выполните команду, в которой имя_таблицы замените на настоящее имя таблицы:
SHOW FULL COLUMNS FROM имя_таблицы;
SHOW FULL COLUMNS FROM GLOBAL_STATUS;
Вы увидите примерно следующее:
Смотрите столбец Collation. В моём случае там utf8_general_ci, это, как и utf8_unicode_ci, кодировка UTF-8. Кстати, если вы не знаете в чём разница между кодировками utf8_general_ci, utf8_unicode_ci, utf8mb4_general_ci, utf8mb4_unicode_ci, а также какую кодировку выбрать для базы данных MySQL, то посмотрите эту статью.
Теперь, когда мы узнали кодировку (в моём случае это UTF-8), то при каждом подключении к СУБД MySQL нужно выполнять последовательно запросы:
SET NAMES UTF8 SET CHARACTER SET UTF8 SET character_set_client = UTF8 SET character_set_connection = UTF8 SET character_set_results = UTF8
В PHP это можно сделать примерно так:
$this->mysqli = new mysqli($server, $username, $password, $basename); if ($this->mysqli->connect_error) < $this->errorHandler_c->logError(1, 'Connect Error (' . $this->mysqli->connect_errno . ') ' . $this->mysqli->connect_error, $_SERVER ['REQUEST_URI']); > $this->mysqli->query("SET NAMES UTF8"); $this->mysqli->query("SET CHARACTER SET UTF8"); $this->mysqli->query("SET character_set_client = UTF8"); $this->mysqli->query("SET character_set_connection = UTF8"); $this->mysqli->query("SET character_set_results = UTF8");
Обратите внимание, что UTF8 вам нужно заменить на ту кодировку, которая используется для ваших таблиц.
Изменение кодировки файлов
Если вы решили пойти другим путём и вместо установки новой кодировки изменить кодировку ваших файлов, то посмотрите статью «Как конвертировать файлы в кодировку UTF-8 в Linux». В ней рассказано, как узнать текущую кодировку файлов и как конвертировать файлы в любую кодировку (не только UTF-8).
Как узнать, какую кодировку отправляет сервер
Если вы хотите узнать, какие настройки кодировки имеет веб-сервер (какую кодировку передаёт в заголовках), то воспользуйтесь следующей командой:
curl URL -s -o /dev/null -D /dev/stdout | grep -E 'charset'
В ней вместо URL вставьте реальный адрес проверяемого сайта. Если сайт использует HTTPS, то укажите адрес сайта вместе с протоколом, например
curl https://softocracy.ru -s -o /dev/null -D /dev/stdout | grep -E 'charset'
Какую кодировку выбрать для веб-сайта
Рекомендуется выбрать кодировку UTF-8. Это более универсальная кодировка, практически, она стала стандартом. У вас не будет проблем с отображением необычных символов и букв из других алфавитов.
Связанные статьи:
Рекомендуемые статьи:
4 Комментарии
Здравствуйте Кажется сервер у хостера сам меняет кодировку. Все файлы юникод база юникод_дженерал_си, кодировка прописана и в хидере и в акцессе На локале всё нормально — тексты (Şərg döyüşlər и другие) отражаются нормально, но у хостера нормально ТОЛЬКО при первой загрузке страницы, а дальше идёт так — ??rg d�y�?l?r. Через фтп гружу в нотпад, а там кодировка АНСИ. Думал проблема в автоопределении кодировок нотпада — отключил эту опцию, файлы начали снова открываться в утф, но на сервере ничего не изменилось. Хостер пока бесплатный, сайт просто тестируются
curl 'https://8km-az.000webhostapp.com/cat.html?id=4' -s -o /dev/null -D /dev/stdout | grep -E 'charset'
content-type: text/html; charset=utf-8
-
??rg d�y�?l?r
Если строки для этих тегов берутся из базы данных, проблема в PHP скрипте, который делает запрос. Как вы сказали, данные в базе данных в кодировке UTF, но PHP скрипт обрабатывает их как другую кодировку, в результате на выходе получается тарабарщика.
Найдите на этой странице пример после строки «В PHP это можно сделать примерно так:» — эти запросы нужно выполнять перед основным запросом к базе данных. Я сам пользуюсь именно таким способом.
То есть да, проблема может быть в хостере — у него может быть другая кодировка по умолчанию для запросов к базам данным. Вы можете это исправить явно указав в PHP нужную кодировку.
Спасибо! Вот это помогло: в файле .htaccess для установки кодировки AddDefaultCharset windows-1251 php_value default_charset «cp1251»