Некорректное отображение текста сайтов на PHP версии 5.6 и выше
07 сентября 2016 года
С введением новых серверов с версией PHP по умолчанию 5.6, к нам стали обращаться клиенты с проблемой отображения сайтов в кодировке WINDOWS-1251. Решение проблемы достаточно простое.
Несмотря на добавление в файл .htaccess кодировки по умолчанию для Apache и указанием кодировки в мета-тегах HTML, проблема не решалась. В заголовках от сервера приходил ответ с UTF-8 и браузер выбирал его.
# Кодировка по умолчанию в файле .htaccess AddDefaultCharset windows—1251 |
# Мета-тег в HTML коде страницы <meta http—equiv=«Content-Type» content=«text/html; charset=windows-1251»/> |
# Заголовок приходящий от сервера Content—Type:text/html; charset=utf—8 |
Проблема появилась из-за изменения кодировки по умолчанию в PHP, начиная с версии 5.6: http://php.net/manual/ru/ini.core.php#ini.default-charset, теперь она жестко задана в UTF-8, а в более ранних версиях просто не задавалась и её можно было легко устанавливать через мета-тег или файл .htaccess
Решением проблемы является добавление строчки в файл .htaccess, которая меняет кодировку на windows-1251:
# Установка кодировки для PHP php_value default_charset windows—1251 |
Данной проблеме подвержены все сайты, кодировка которых отличается от UTF-8 и скрипт в процессе работы не устанавливает параметр default_charset. К нам в основном обращаются с проблемой после установки сайтов на DLE (данная CMS работает в windows-1251).
Если Вы ищете тестовый хостинг для сайта wordpress, то LITE.HOST это то, что Вам нужно. Мы также оказываем услуги по хостингу php и не только. Переходите в раздел «Хостинг» и выбирайте удобный для Вас тариф.
-
#1
default_charset в php.ini
Народ подскажите плз, как в этом параметре (default_charset) прописывать виндовую кодировку. Если koi8-r так скорее всего и пишется, то как прописывать win-1251 или cp1251, и как юникод? И вообще можно ли это делать?
Заранее спасибо
RomikChef
Guest
-
#2
ЧЕГОООО?!
какой еще дефолт чарсет в php.ini ???
-
#3
>И вообще можно ли это делать?
Для php-gtk можно делать.
-
#4
2: RomikChef
; As of 4.0b4, PHP always outputs a character encoding by default in
; the Content-type: header. To disable sending of the charset, simply
; set it to be empty.
;
; PHP’s built-in default is text/html
default_mimetype = «text/html»
default_charset = «windows-1251»
2: hussar
А зачем оно тебе вообще надо? Это только лишь определяет кодировку по умолчанию, если ты сам не сделал этого при помощи META или соотв. хэдера. Т.ч. чем мучать php.ini, выдай любыми подручными средствами php (да хоть echo) META HTTP-EQUIV=»Content-Type» CONTENT=»text/html; charset=windows-1251″ или, для юникода, charset=utf-8.
Apache Manager
Guest
-
#5
Очень рото все , если юзаешь апач, то в файле .htaccess
пропиши вот это
AddDefaultCharset windows-1251 тока в той папке де у тя скрипты лежат =)
-
#6
Ок, спасибо за объяснения Попробую сделать. А надо мне это для того, что я пытаюсь понять в каком месте у меня сбиваются кодировки. Есть программа которая через форму которая передает данные в MS SQL SERVER 2000, данные передаются и даже выводятся обратно, но в самой базе при просмотре таблиц — это нечитаемые кракозябры , и иногда при выводе тоже некоторые кирилические буквы заменяются на латинские. Вот такая проблема и я не могу понят в чем тут дело то-ли в базе то ли в кодировке страницы, то-ли в PHP.
Если кто-то сталкивался с подобной проблемой, буду очень благодарен за совет
LASSO, да, действительно. Спасибо.
Почему я задал такой вопрос: пытаюсь расставить приоритеты в заголовках кодировок. Вот к чему я пришёл …
Директива «AddDefaultCharset», прописанная в конфигурационном файле сервера «Apache» [httpd.conf], определяет какую кодировку будет указывать сервер при отдаче клиенту файлов, всех по умолчанию; причём она обладает большим приоритетом, нежели HTML-элемент «meta» с атрибутом «charset», который указывает кодировку непосредственно в документе HTML. Однако файлы, которые обрабатывает PHP, сопровождаются не «общим» заголовком сервера, а заголовком PHP, который также имеет преимущество над заголовком HTML-элемента.
Итого (в порядке уменьшения): PHP → «Apache» → <meta>.
Добавлено через 6 минут
P. S. По поводу «mbstring.internal_encoding» также появились вопросы, но на данном этапе меня интересовало именно то, о чём я сказал, к тому же у меня пока ещё недостаточно знаний по «mbstring», поэтому данную тему оставим на следующий раз ☺.
Кодировки
версия для печати
Мои сайты сделаны в кодировке windows-1251, включая БД. Возникла необходимость получить файл в кодировке UTF-8 (собираю dump-файл базы). Как оказалось, преобразование из одной кодировки в другую — задача не тривиальная. В этой статье я попытаюсь разложить по полочкам, что к чему. Поле деятельности: Apache/2.2.15 (Win32) PHP/5.3.5. Во внимание беру только две кодировки, UTF-8 и Windows-1251 (aka cp1251), но многое из сказаного относится к преобразованиям в любых кодовых страницах.
Прежде чем хвататься за клаву и «превращать воду в вино»..
часть Рекомендательная
Настройка кодировки PHP-препроцессора (php.ini или .htaccess), параметр default_charset. Он нужен для указания браузеру, в какой кодировке передается ответ (не обязательно html-страница). Это указание передается в заголовках (HTTP headers) ответа. Причем в мета-теге html-страницы может быть другая кодировка или не быть вообще, это отдельная история. Если в заголовках кодировка не указана, нормальный браузер (типа FireFox) пытается сам ее определить по содержимому или по мета-тегу, если он есть.
Аналогичная картина наблюдается для web-сервера Apache. Кодировка ставится директивой addDefaultcharset. Ее можно указывать в конфиге httpd-vhosts.conf (секция <directory>, потребуется перезапуск сервера), или в .htaccess сайта. Зачем нужна отдельная директива Apache? Это очевидно: на PHP свет клином не сошелся, web-сервер может и без него формировать ответы на запросы браузера, вот для таких ответов можно указывать конкретную кодировку.
Приведу несколько примеров получающихся заголовков.
Настройки PHP: windows-1251 (php.ini: default_charset=windows-1251)
HTTP/1.1 200 OK
…
Content-Type: text/html; charset=windows-1251
Настройки Apache: UTF-8 (.htaccess: addDefaultcharset UTF-8)
HTTP/1.1 200 OK
…
Content-Type: text/html; charset=UTF-8
Настройки PHP и Apache: не указана кодировка
HTTP/1.1 200 OK
…
Content-Type: text/html;
часть Функциональная (PHP)
Переключить кодировку PHP-препроцессора на время выполнения скрипта можно так:
ini_set(‘default_charset’,’UTF-8′);
С другой стороны, перед передачей ответа можно явно указать заголовок с кодировкой:
header (‘Content-Type: text/html; charset=windows-1251’);
Кодировка файла скрипта. PHP-файл — это обычный текстовик, все символы в нем кодируются набором байт с учетом установленной кодировки текста. Если в скрипте используются функции типа echo(), fwrite() и т.п., причем текст их параметров записан в этом же скрипте, то здесь так же важна кодировка самого файла скрипта! Пример файла some.php:
<?php echo 'Pусский текст в UTF-8'; ?>
Чтобы в браузере этот текст был действительно в UTF-8, кодировка файла с приведеным кодом должна быть UTF-8. Посмотреть и исправить кодировку файла можно, например, в Notepad++. У меня php-редактор (Blumentals Rapid PHP 2010) так же устанавливает кодировку для новых файлов.
БД, внешние файлы. Если кодировка текста, полученного из таблицы/файла/сайта, отличается от нужной, то придется перекодировать. В этом месте наконец-то можно использовать функции типа iconv(), utf8_encode(), ob_iconv_handler(), mb_output_handler() и т.п., а так же пользовательские функции перекодирования.
Назначение всех этих функций разное. Например, utf8_encode() поддерживает только следующее преобразование: ISO-8859-1 (aka Latin-1) > UTF-8. Две других функции, ob_iconv_handler() и mb_
output_handler(), можно использовать только как callback-функции для буфферизированного вывода (этот момент до меня долго доходил). Пример использования: здесь источником текста является сам скрипт (кодировка файла: UTF-8), настройки web-сервера и PHP не суть важны, в браузере можно переключиться.
echo 'русский текст в UTF-8<BR>';
iconv_set_encoding("internal_encoding", "UTF-8"); //"входящая" кодировка
iconv_set_encoding("output_encoding", "WINDOWS-1251");//кодировка перед выдачей из буфера
ob_start('ob_iconv_handler'); //назначаем доп. обработчик
echo 'русский текст в WINDOWS-1251<BR>';
ob_end_flush();
Результатом в браузере будут две строки, первая будет читаться при выборе кодировки страницы «UTF-8» (см. в настройках браузера), вторая — «Кириллица (Windows-1251)». Это был учебный пример, реальное применение перекодирования «на лету»: нужно вернуть пользователю html-страницу в другой кодировке.
Замечание: если callback-функции в случае ошибки вернут «false» вместо новой строки, вывод информации не остановится и сообщений не будет, получится текст без перекодирования.
В моей задаче (получение UTF8-файла) пришлось применять функцию iconv() к каждой записываемой в файл строке.
Создание файла с нужной кодировкой. Тут вроде особых проблем нет, используем iconv() или сразу пишем в нужной кодировке. Зато есть ньюанс с UTF-8 файлами. Следующий код создает файл с кодировкой UTF-8 (файл скрипта в той же кодировке):
$text="русский текст, english text\nВторая строка";
$file=fopen('some.txt','w+b');
//fwrite($file, pack("CCC",0xEF,0xBB,0xBF)); //Пишем сигнатуру UTF-8
fwrite($file, $text);
fclose($file);
Некоторые программы не корректно определяют кодировку полученного файла. Выход: дописывать сигнатуру UTF-8 в начале файла. Для этого нужно раскоментировать строку (3). Что такое «сигнатура UTF-8«, цитата из Википедии:
«Порядок байтов (BOM, сигнатура)
Многие программы Windows (включая Блокнот) добавляют байты 0xEF, 0xBB, 0xBF в начале любого документа, сохраняемого как UTF-8. Это метка порядка байтов Юникода (англ. Byte Order Mark, BOM), также её часто называют сигнатурой (соответственно, UTF-8 и UTF-8 with Signature). По наличию сигнатуры программы могут автоматически определить, является ли файл закодированным в UTF-8, однако файлы с такой сигнатурой могут некорректно обрабатываться старыми программами, в частности xml-анализаторами. Такие редакторы, как Notepad++, Notepad2 и Kate позволяют явно указывать, следует ли добавлять сигнатуру при сохранении UTF-файлов.»
Post Scriptum
Нашел на форумах пользовательскую функцию преобразования windows-1251 <-> UTF-8. Может пригодится когда-нибудь. У меня она работала криво в направлении Win -> UTF. Пофиксил, все работает:)
function Encode($str, $type='w2u'){
// 'u2w' - кодировать из UTF в win
// 'w2u' - кодировать из win в UTF
$conv=array ();
for ($x=128; $x<=143; $x++){
$conv['utf'][]=chr(209).chr($x);
$conv['win'][]=chr($x+112);
}
for ($x=144; $x<=191; $x++){
$conv['utf'][]=chr(208).chr($x);
$conv['win'][]=chr($x+48);
}
$conv['utf'][]=chr(208).chr(129);
$conv['win'][]=chr(168);
$conv['utf'][]=chr(209).chr(145);
$conv['win'][]=chr(184);
if ($type=='u2w') return str_replace ($conv['utf'], $conv['win'], $str);
elseif ($type=='w2u'){
//return str_replace ($conv['win'], $conv['utf'], $str); //баг
$arr=array_combine($conv['win'], $conv['utf']);//корректно работает
return strtr($str,$arr);
}
else return $str;
n}
Баг был в
строке (20): функция str_replace() гонит на половине алфавита. Заменяет русскую win-букву на двухбайтное UTF-значение, а потом а этой замене опять заменяет первый байт(!), который в win-1251 так же соответствует букве, на UTF-значение. Причем другая половина алфавита нормально заменяется.
Таблица соответствия Unicode/UTF-8 <-> Windows-1251 (и не только) http://www.utf8-chartable.de
[1oo%, EoF]
Понравилась статья? Расскажите о ней друзьям:
Материал из Wiki — Iphoster — the best ever hosting and support. 2005 — 2025
Перейти к:навигация, поиск
VestaCP — Кодировка при обработке php в html файлах
При включении обработки php в html файлах бывает неверно отображается кодировка в html файлах:
AddHandler application/x-httpd-php .php .php3 .php4 .htm .html .shtm .shtml
решение — это поставить корректный default_charset в php.ini
default_charset = "windows-1251"
или
default_charset = "UTF-8"
для CentOS 6 это
/etc/php.ini
для Debian это:
/etc/php5/apache2/php.ini /etc/php5/cgi/php.ini /etc/php5/cli/php.ini
Важно! Не забудьте перезапустить apache после внесенных изменений.