Среда , 18 Январь 2017
Конкурс «Книга за вопрос»
ДомойПубликацииразные кодировки в php

разные кодировки в php

php

начинающим скриптописателям глубоко плевать на такое понятие, как кодировка. поэтому на сайтах иногда можно встретить жуткую кашу, когда данные из бд получаются в одной кодировке, страница формируется в другой, а сервером отдаётся третья. в результате страницу если и можно расшифровать, то минимум с 2 раз. итак, отчего же такая беда случается и как её побороть?

в русском сегменте чаще всего можно встретить так называемую windows-кодировку. называют её по разному: windows-1251, cp1251 или даже ansi. следующей идёт utf-8. можно встретить также название unicode, но это не совсем корректно, т. к. юникод общее название для целой группы (utf-8, utf-16, utf-32). и уж совсем раритетом является популярная koi8-r или просто кои-8 — некогда популярная линуксовская кодировка. конечно, можно в русском сегменте встретить и что-то другое, но это скорее является «баловством» автором.

основное отличие utf-8 от прочих (в первую очередь windows-1251 и koi8-r) — последние являются однобайтовыми, и максимальное количество символов, которые можно представить с помощью данных кодировок ограничего числом 256. само-собой, что для полноценного представления текста этого может быть недостаточно. и для html был найден выход — использование так называемых мнемоник. например, так:

© — ©

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

таким образом, наиболее комфортный набор начальных условий такой: кодировка базы данных, php-скриптов и html-страниц/js-скриптов должна быть одной и той же. конечно, можно использовать и разные, но в этом случае есть риск запутаться. при этом не важно, какая именно кодовая страница используется. если сайт будет только для русскоязычной аудитории, windows-1251 будет вполне достаточно. иначе логичным выбором будет utf-8. с первым вариантом всё более-менее понятно. а для многобайтной кодировки потребуются некоторые телодвижения.

при работе с utf-8 стандартный виндусовский notepad не подойдёт! дело в том, что данный редактор, при сохранении файла в этой кодировке, добавляет в начало сигнатуру — 3 символа, так называемый bom (byte order mark), по которому при открытии файла можно определить кодировку. лучше выбрать другой редактор: notepad2 или notepad++. в настройках обязательно выбрать сохранение без сигнатуры.

следующий важный шаг — работа с базой данных. крайне желательно, чтобы кодировка базы/таблицы/текстового поля совпадали с кодировкой скрипта (это может быть cp1251 или utf-8, или что-нибудь другое). если данные из базы получаются в виде «зюков», скорее всего кодировка соединение отличается от данных, хранящихся в бд. следующий запрос поможет побороть ситуацию (выполнить сразу после соединения с базой):

SET NAMES utf8

если на сайте используется windows-1251, следует указать её — cp1251.

в общем-то, нет ничего сложного. единственно, стандартные функции php не предназначены для работы с многобайтовыми строками. но есть стандартные библиотеки, которые помогут исправить ситуацию: iconv и mbstring. для регулярных выражений также существует необходимый переключатель, который активируется с помощью модификатора u.

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

header('Content-Type:text/html; charset=utf-8');

если используется однобайтовая кодировка, то значение для charset будет другим — windows-1251. после этого проблем остаться не должно.

несколько простейших примеров работы с utf-8 на php:

пример 1: iconv, количество символов в строке

$s = 'строка'; # строка в utf-8
$cnt1 = strlen($s); # будет содержать значение 12
$cnt2 = iconv_strlen($s, 'UTF-8'); # правильное значение, 6

пример 2: mbstring, количество символов в строке

$s = 'строка'; # строка в utf-8
$cnt1 = strlen($s); # будет содержать значение 12
$cnt2 = mb_strlen($s, 'UTF-8'); # правильное значение, 6

пример 3: регулярные выражения, поиск и замена

$s = 'Строка'; # строка в utf-8
$s = preg_replace('/стр/i', 'д', $s); # замена не произойдёт
$s = preg_replace('/стр/iu', 'д', $s); # результат слово дока

модификатор i предписывает регистронезависимый поиск, а модификатор u говорит движку регулярных выражений работать с utf-8 строками.

если кто-то скажет, что php не может работать с utf-8, он будет не прав. уже несколько лет делаю все свои проекты в этой кодировке и проблем не было совершенно. поисковые системы сами давно используют эту замечательную кодировку.

Поддержать проект

WebMoney

Яндекс.Деньги


Рейтинг: 0

Автор публикации

1 203
не в сети 51 минута

x64 (aka andi)

Комментарии: 1846Публикации: 303Регистрация: 02-04-2009
Так себеНеплохоХорошоЗамечательноСупер! (1 голосов, в среднем: 5,00 из 5)
Загрузка...

4 комментария

  1. Надежда Давыдова

    Вот немного узнала, что это за bom. Я пользовалась Akel Pad, чтобы сохранять файл в UTF-8 без bom. Знаю уже трех профессиональных программистов, но только на твоем сайте вижу небольшой экскурс в ваши святая святых smile

    Рейтинг: 0
    • Надежда, так дело в том, что это кажется настолько естественным и понятным всем, что можно с дыханием сравнить.
      Со временем забываются моменты, которые вызывали трудности, а подобные вопросы вызывают лишь недоумение: «что же тут непонятного?», хотя когда-то сам ничего не понимал.
      Помню, как с парнем одним общались, обсуждали проблемы записи текста в базу данных (текст добавлялся «битым», поэтому приходилось делать финт ушами: перед записью в базу он переводился в кодировку cp1251, а после извлечения — снова преобразовывался в UTF-8). Хотя проблем-то никаких не было, всего 1 SQL-запрос решал всё. laugh

      Рейтинг: 0
      • Надежда Давыдова

        Не знаю как насчет программирования, но вот верстку собираюсь изучить детально. Смотрю, сколько проблем нерешенных вокруг (я имею ввиду сайты), в том числе и у меня. Малыш подрастет,немного появится времени. Хочу сверстать свою тему или десять тем. И как там поет ДДТ «… и всю жизнь получать гонорар» smile

        Рейтинг: 0
        • Кстати, очень хорошая задумка. Верстальщиков-то много, но отличных верстальщиков, увы, мало.
          Желаю всяческих успехов на данном поприще!
          Ведь, как известно, терпение и труд — всё, перекур (:

          Рейтинг: 0

Оставить комментарий

Ваш email не будет опубликован.Необходимы поля отмечены *

*

Добавьте изображение (jpg/gif/png)

Авторизация

Регистрация

Пароль не введен

Генерация пароля