Преобразовать windows 1251 в utf 8 php

Обновлено: 04.07.2024

На сколько бы это глупо не казалось, но для удачного выставления кодировки необходимо выполнить целых 11(!) правил.
Хочу зарание предупредить, если какая-то из настроек в .htaccess повлечет за собой ошибку 500, это значит, что хостинг запретил менять этот параметр на сервере. В таком случае проверьте тот факт, что у Вас UTF-8 и в случае чего обратитесь к админам хостинга.
И для тех, кто попал на эту страницу с вопросами об Ajax: Ajax работает в кодировке UTF-8.

Правило №1: Указываем в HTML верстке в теге первой строчкой, кроме случаев, где мы будем использовать тег , так как он так же как и кодировка имеет приоритет над расположением, следующий код:


Правило №2: Указываем кодировку для PHP и самого файла, для этого нам необходимо выставить заголовок функцией header(). Выставляем его в самом начале нашего файла (абсолютно в самом начале), сразу после указания уровня вывода ошибок:

Правило №3: Кодировка для подключения к к БД MySQL. Устанавливается после подключения к БД и выбора бд (mysql_connect, mysql_select_db). Если у нас модуль mysql:

или улучшенный модуль mysqli:


Правило №4: Кодировка в .htaccess:


Правило №5: Кодировка для библиотеки mb, начиная с версии php 5.4 можно не указывать, так как по умолчанию будет использоваться именно UTF-8. Ну а пока прописываем её в файле .htaccess:

Либо в самом PHP, что в итоге выполнит одни и те же действия:


Правило №6: При сохранении файлов (обязательно ВСЕХ!) выбрать кодировку UTF-8 without BOM, повторюсь, without BOM - это необходимая настройка, в противном случае Ваш сайт не будет работать как надо. Для тех, кто пользуется удобной программой DreamWeaver:
Modify => Page Properties => Title/Encoding и выставляем "Encoding: UTF-8", после чего нажимаем ReLoad, убираем галочку с BOM "Include Unicode Signature (BOM)". Apply + OK.
Модификации => Свойства страницы => Заголовок/Кодировка и выставляем кодировку UTF-8. Нажимаем "перезагрузить", убрали галочку с Подключить Юникод Сигнатуры (BOM). Применить и OK.

Правило №7: если на данный момент какой-то из текстов был введён на странице или в БД - его необходимо перенабрать. Дело в том, что символ в одной кодировке представляет один набор бит для русских символов, а в другой - другой. Именно поэтому необходимо его либо перенабрать, либо перекодировать. Современные программы имеют возможность перевести текст из одной кодировки в другую. Об этой возможности интересуйтесь в мануалах Ваших программ.

Правило №8: Есть исключение, когда текст приходит к Вам на страницу с другого сайта в другой кодировке. Тогда на PHP есть удобная функция для перевода из одной кодировки в другую:


Правило №9: Для строковых функций strlen, substr, необходимо использовать их аналоги на библиотеке mb_, а именно: mb_strlen, mb_substr, то есть к функции дописываем mb_ .

Правило №10: Для работы с регулярными выражениями необходимо указывать модификатор u . Это обязательный параметр!

Правило №11: Для CSS файлов указывается кодировка так:


В заключение скажу, что символы в кодировке WIN-1251 состоят из 1 байта, то есть 8 бит, а в свою очередь в кодировке UTF-8 символы могут состоять от 1 до 4 байт, всё дело в том, что кодировка UTF-8 позволяет создавать мультиязычные сайты, так как все существующие в мире символы в ней присутствуют.
Ради любопытства русская буква в кодировке UTF-8 занимает 2 байта, именно поэтому за 1 символ функция strlen возвращает длину 2, то есть 2 байта, а mb_strlen возвращает уже правильную длину в 1 символ.

Если вы здесь, значит и вы пришли на эту страницу ища ответ как изменить кодировку строки на PHP. Ну да ладно, меньше воды, больше дела. Приступим. Для начала нам нужно создать строку или же принять ее с супер глобального массива $_POST . Для этого будет примерно такой код:

Теперь когда у нас записана информация в переменной $string , можно изменить кодировку строки. Обычно для этого используется встроенная функция PHP, и называется она iconv .

Синтаксис функции выглядит примерно так:
переменная для результата = iconv("текущая кодировка","кодировка в которую конвертируем","конвертируемая строка");

То-есть если нам надо изменить кодировку строки которая хранится в переменной $string с текущей кодировкой utf-8 на windows-1251, стоит написать всего одну строчку кода, и все будет готово:

Теперь расскажу о решении проблемы с каракулями в базе данных. Здесь тоже нет ничего особенного, всего лишь одна строчка поможет вам. Логика работы такая:

  1. Подключаемся к серверу БД
  2. Выбираем базу данных
  3. Выполняем команду: SET NAMES ‘chcp1251′

Вся работа как раз и состоит в этой последней строке. Эта команда заставляет работать mysql БД по умолчанию с кодировкой windows-1251, и теперь в таблицу не будут записываться разные каракули 😉

Для этого нужно написать в PHP такую строку кода:

И последнее о чем хотел рассказать о смене кодировки на PHP. Обычно когда на сервере для передачи данных используют технологию AJAX, скрипт-обработчик работает с кодировкой windows-1251, а как раз JQuery при отправке данных работает с utf-8.

Поэтому при обработке и дальнейшей отправке ответа клиенту, в браузер выводятся также различные каракули. Для этого нужно при принятии данных на PHP (скриптом-обработчиком) конвертировать весь глобальный массив $_POST в кодировку windows-1251. Вот он, заветный код изменения кодировки POST массива:

Теперь после конвертации кодировки всего POST , у нас не будут больше выводится каракули на страницу пользователям. На этом закончу статью, надеюсь было полезно;)

Забегая на перед можно с уверенностью сказать, что на сегодняшний день следует использовать исключительно кодировку UTF-8. Это, конечно, не означает, что нужно конвертировать из win-1251 в UTF-8 все, особенно не поддерживаемые более сайты, но задуматься о переводе активно развиваемых проектов нужно было еще, как говорят, вчера. Потребность в конвертации сайта из win-1251 в UTF-8 возникает по многим причинам, но для начала следует разобраться, в чем же принципиальная разница этих кодировок? Самое главное отличие - количество символов, которые могут содержаться в каждой из них.

Кодировка Windows-1251 может содержать не более 255 символов, так как все символы этой кодировки кодируются одним байтом. Из-за этой особенности, такие кодировки, как win-1251 еще называют "однобайтными". В состав Windows-1251 входят символы кириллического, латинского алфавитов, знаки препинания и некоторые другие символы. Из-за столь ограниченного набора символов, вывести в Windows 1251 символы китайского иероглифа (供) или, например, немецкого умляута (ö) невозможно.

Можно предположить, как делают множество создателей кириллических сайтов, что для проектов, на которых будут использоваться только кириллица или латинские символы кодировка utf-8 ни к чему. Еще больше, в приоритете использования Windows-1251 может убедить тот факт, что символы этой кодировки занимают меньше места, и в следствие чего немного быстрее обрабатываются строковыми функциями PHP.

Подробнее про кодировку UTF-8 можно узнать из материалов Википедии .

Перекодирование сайта в UTF-8

Перекодирование скриптов сайта из win-1251 в UTF-8 - это далеко не простое занятие, как может показаться на первый взгляд. Необходимо проделать большой объем работы, вкратце рассмотренный ниже:

Большинство сложностей с конвертацией сайта из win-1251 (или любой другой однобайтовой кодировки) в UTF-8, в первую очередь вызваны тем, что PHP, даже самая новая версия (на момент написания статьи 5.4), не полностью поддерживает кодировку UTF-8. Поскольку большинство символов в UTF-8 закодированы двумя (до четырех) байт - обычные строковые функции не правильно работают с такими символами. Пример ниже следует набирать в UTF-8:

Вместо ожидаемого вывода "Проверк" получаем "Про" и "крокозябл" в конце - "�". Обычные строковые функции PHP предназначены для работы с однобайтными кодировками, символы которых состоят из одного байта, вот функция substr() и вырезает первые семь байт соответствующие симовлам "П,р,о" (кириллические буквы в UTF-8 кодируются 2-мя байтами) и первому байту буквы "в", вследствие чего "в" и превращается в "крокозябл �".

Далее будут рассмотрены способы, как подружить строковые функции PHP с кодировкой UTF-8.

Редактирование скриптов в кодировке UTF-8

Для редактирования скриптов в кодировке UTF-8 необходим редактор, который не только понимает эту кодировку, но и не добавляет специальный символ BOM , из за наличия которого скрипты могут вести себя неожиданным образом.

В качестве редактора PHP-кода можно посоветовать бесплатный NetBeans или платные редакторы PhpStorm (99$), Zend Studio (299$). Поскольку это не обычные редакторы, а так называемые IDE (интегрированная среда разработки) - дополнительный функционал этих программ будет весьма кстати при рефакторинге кода для UTF-8.

Конвертация данных в MySQL

Перед конвертацией данных в базе MySQL из Windows-1251 в UTF-8 необходимо обязательно выполнить резервное копирование конвертируемой БД, в противном случае можно безвозвратно потерять все или часть данных! Следует обратить внимание, что в MySQL кодировка Windows-1251 называется cp1251, а UTF-8 - utf8.

<?php
$mysqlhost = '' ;
$mysqlusers = '' ;
$mysqlpass = '' ;
$dbname = '' ;


echo '<h1>Кодировка соединения с БД: <span style="color: orange; font-size: 70px;">' . $mysql_charset_conn . '</span></h1>
' . $db_charset . '
' . $table_found . '' ;
?>

После преобразования данных в таблицах MySQL из cp1251 в utf8 необходимо изменить кодировку по умолчанию для скриптов (изменение настройки в my.ini / my.conf или SQL запросом SET NAMES utf8 каждый раз после подключения к БД). Также следует заменить заголовок с указанием кодировки, отправляемый сервером браузеру клиента. Это можно сделать изменив в HTML-коде строку, расположенную между дескрипторами <head>. </head>

или выведя заголовок непосредственно средствами PHP:

Эти два способа указания кодировки браузеру можно совместить.

Теперь, вся информация из БД будет выводиться на страницах сайта как положено, а вот все тексты не латинскими буквами, расположенные в скриптах, отобразятся "кракозяблами". Для превращения "кракозяблов" в нормальный текст необходимо перекодировать уже сами скрипты, о чем речь пойдет в следующем разделе.

Перекодировка скриптов из Windows-1251 в UTF-8

Поскольку латинские буквы и знаки препинания имеют одинаковые коды символов как в кодировке Windows-1251 и так и в UTF-8 - проблем с их отображением не возникнет. В связи с этим ни код PHP, ни HTML-разметка, заданная латинскими буквами и знаками препинания практически не пострадают. Другое дело - кириллический алфавит.

// Конвертер модуля ссылок

После изменения кодировки файлов необходимо прописать или изменить локаль (предварительно, стоит ознакомиться с документацией по функции setlocale() , чтобы избежать проблем из-за отличий в операционных системах):

Эта строчка должна присутствовать вначале каждого скрипта.

После этих действий, весь сайт, скорее всего, отобразится как положено. "Скорее всего" потому, что еще необходимо внести изменения в коде скриптов, т.е. произвести рефакторинг кода - решить проблему со строковыми и некоторыми другими функциями PHP при работе с кодировкой UTF-8.

Строковые функции PHP и UTF-8

Как было написано ранее, обычные строковые функции PHP (strlen(), substr(), strtolower() и др.) корректно работают только с однобайтными кодировками. Для мультибайтных кодировок, одной из которых и является UTF-8, необходимо применять специальные функции, например, из расширения PHP Mbstring .

Исключением является функция strlen(). В однобайтной кодировке, функция, возвращая количество символов, возвращает и размер строки в байтах, поскольку, как уже говорилось ранее, каждый символ в таких кодировках равен одному байту, и, соответственно, количество символов строки равно размеру в байтах. Заменять такую функцию, например на mb_strlen() нужно только тогда, когда задача strlen() была в подсчете количества символов. Если же strlen() использовалась для подсчета размера строки в байтах с последующей передачей этих данных, например в заголовок HTTP отправляемый клиенту для указания размера передаваемых данных - её следует оставить без изменений. Например, необходимо узнать размер и кол-во символов строки "строка, передаваемая клиенту":

echo 'Строка состоит из: ' . $strlen . ' байт и ' . $mb_strlen . ' символов.' ;
// 53 байта, 28 символов
?>

(В кодировке UTF-8 кириллические символы занимают 2 байта, пробел и запятая - 1 байт)

Есть несколько решений этой проблемы: перезагрузка функций, замена обычных строковых функций в коде на функции с приставкой "mb_" и использование функций написанных сторонними разработчиками или самостоятельно.

Перезагрузка функций

Перезагрузка функций - это указание интерпретатору PHP воспринимать часть обычных функций, работающих с однобайтовыми кодировками как функции MBString - со списком перегружаемых функций можно ознакомиться в официальной документации PHP ). Чтобы выполнить перезагрузку функций необходимо в главном конфигурационном файле PHP (php.ini) установить параметр:

Ранее, до версии PHP 5.2.7, изменение настроек перезагрузки функций можно было осуществить в файле .htaccess (php_value mbstring.func_overload 2), но в более поздних версиях эта возможность, к сожалению, не доступна.

Если необходимо установить/отключить перезагрузку функций только для одного/нескольких сайтов следует воспользоваться директивой php_admin_value mbstring.func_overload 2 в конфигурации сервера Apache для виртуальных хостов.

Замена строковых функций

Для замены функций на MB-аналоги как раз и пригодится один из редакторов, о которых говорилось выше. Предлагаемый способ замены тестировался в NetBeans, но скорее всего он будет аналогичен и в других IDE.

Перед использованием функций из MBString необходимо установить внутреннюю кодировку скрипта в UTF-8 при помощи функции mb_internal_encoding(), которая должна выполнятся перед использованием всех функций MBString в скриптах

Также, задать внутреннюю кодировку скрипта можно в конфигурационном файле PHP - тогда этот параметр распространится на все скрипты.

Для начала следует создать проект в NetBeans, в который должны быть включены все скрипты, обслуживающие сайт. Далее, для замены, например функции substr(), необходимо создать собственную функцию substr() в новом файле подключенном к проекту, иначе рефакторинг произвести не удастся:

Потом на функции subst() нужно нажать правой кнопкой мыши и из меню выбрать: Refactor -> Rename, в поле New Name изменить subst на mb_substr и нажать кнопку "Preview":


Теперь можно заменить все функции сразу во всех файлах проекта, либо предварительно просмотреть в каком контексте используется substr() в коде каждого файла скрипта - байты или символы.

На что еще следует обратить внимание

Регулярные выражения и UTF-8

Чтобы регулярные выражения в функциях preg_. () работали корректно, необходимо добавить модификатор шаблона u . Также, следует забыть о шаблоне \w, и заменить его на \pL, хотя лучше всего использовать такую конструкцию [а-я].

Функция iconv()

Необходимо найти все вызовы функций iconv() в коде скриптов сайта, и заменить кодировки, либо вообще убрать эту функцию там, где из UTF-8 символы перекодировались в Windows1251.

Если сайт работает с ситемой Сапе (на сайте размещаются ссылки), необходимо изменить код подключения Сапе и вместо $sape = new SAPE_client() нужно написать:

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

вместо заголовка пустота. Если выставить iconv без условия, cp1251 кодирует нормально, а utf8 выдает кракозябрами. __________________
Помощь в написании контрольных, курсовых и дипломных работ здесь

Перекодировка из UTF-8 в cp1251 ( AJAX и PHP )
Здраствуйте! Нужен совет по AJAX. Вот файл с AJAX: &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML.

Функция перекодировки utf8 -> cp1251 с поддержкой казахских символов
Выкладываю сюда (т.к. не нашел более подходящего места) функцию, которая корректно перекодирует все.

Перекодировка строки из UTF8 в cp1251
Доброго времени суток. Почему не получается из UTF8 преобразовать в cp1251? std::string.

Перекодировка строки из cp1251 в UTF8
Доброго времени суток. У меня есть строка в cp1251, но мне нужно вывести в utf8. Как это лучше.

на счет iconv() читал, кажется на хабре, что она некорректно конвертирует истроки и в каком-то случае она вообще возвращает строку без изменения кодировки. сейчас не могу найти исходник этого метода Меня терзают смутные сомнения, а выполняется ли мое условие а вы сделайте дапм переменной - выведите её значение и посмотрите на неё вообще-то кодировка указывается на в title, а в заголовках meta:

разберитесь как правильно получить кодировку, которую использует страница

кастати, нашел кажется почти то, что вам нужно (адаптируете под свою задачу) вот тут

вообще-то кодировка указывается на в title, а в заголовках meta: Это я понимаю ). Я получаю title (в виде текста), проверяю его кодировку и , если кодировка cp1251, кодирую ее в utf-8. Вроде так? отлично кодирует, но если текст в utf8, выходят иероглифы.

определение кодировки из полученного текста неблагодарное дело ибо оно опирается на статистический вес буквы
гораздо удобнее из заголовка взять charset и, опираясь на него, выяснить что за кодировка

обратите снимание что если в php.ini установлена кодировка windows-1251 или другая, то даже если вы заголовок поставите urf-8, кодировка будет та, которую установит php-машина. потому если случаются такие каверзы используйте set_ini(. ..)

у меня такая проблема была

так да, берет. я же не говорил что не берет

В cp1251 русские буквы А-Яа-я (без буквы Ёё) занимают диапазон ASCII кодов 192-255 (0xC0-0xFF), а в юникоде - 1040-1104 (0x0410-0x044F). Разница как раз 848.

Буква Ёё отдыхает, я так понимаю. Кустарный способ.


из utf8 в cp1251
Всем привет ! Собственно сразу вопрос - как троку перекодировать из utf8 в cp1251 и обратно ? .

преобразования utf8 <-> cp1251
Какими функциями лучше всего воспользоваться для преобразований utf8 в cp1251 и обратно ?

Перекодировка DBF файла из cp1251 в UTF-8
Есть dbf файл (база БИК), он сохранен в cp1251, как данные из него перекодировать в UTF-8? сам.


Из кода символа Cp1251 получить UTF8 символ
Мучаюсь с быстрым выводом текста на канву (пишу текстовый редактор) пробовал вывод теста.

Читайте также: