Сложности с многобайтными кодировками в PHP

Статьи -> Программирование -> PHP

Сложности с многобайтными кодировками в PHP

v: 2.0 16.02.2010

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

Давайте разберемся, что такое многобайтная кодировка.
Многобайтной кодировкой называют кодировку, в которой один символ представлен несколькими байтами.
Типичным примером многобайтной кодировки является UTF-8. UTF-8 набирает все большую популярность в Web-программировании, поэтому рассмотрим именно ее.
Вот что говорит Викпедия по поводу многобайтности UTF-8:

Символы, закодированные в UTF-8, могут быть длиной до шести байт, однако стандарт Unicode не определяет символов выше 0x10ffff, поэтому символы Unicode могут иметь максимальный размер в 4 байта в UTF-8.

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

Поскольку есть многобайтные кодировки, то должны быть и однобайтные.
В качестве примера однобайтной кодировки можно взять - ASCII
Справка из Викпедии:

ASCII представляет собой 7-битную кодировку для представления десятичных цифр, латинского и национального алфавитов, знаков препинания и управляющих символов. В компьютерах обычно используют 8-битные расширения ASCII

Т.е. в кодировке ASCII, один символ представлен одним байтом.

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

Substr( 'Тестовая строка', 0, 4);

А вот результат, зависит от того в какой кодировке находится строка.
Если кодировка ASCII, то результат будет, как и ожидается, 'Тест'.
А в случае UTF-8 результат изменится на 'Те'.
Причина такого отличия заключается в особенности работы функции substr.
Substr работает не с символами строки, а с байтами. Поэтому, если строка в однобайтной кодировке, т.е. число байт равно числу символов, то функция отработает корректно. Если же количество байт не равно количеству символов, то результат будет неверным.
В данном примере substr отрезал от строки четыре байта. Символы кириллицы кодируются в UTF-8 двумя байтами, вот и получилось в результате два символа, вместо четырех. Если бы мы отрезали нечетное количество символов, то в результате получили бы "усечение" последнего символа, это бы и вызвало странный визуальный эффект в конце строки.

Для корректной работы с многобайтными кодировками в PHP предусмотрен набор функций, их легко можно узнать по наличию приставки mb_
Рассмотри корректный код усечения строки в многобайтной кодировка:

  mb_internal_encoding("UTF-8");       // указываем нужную кодировку
  mb_substr( 'Тестовая строка', 0, 4); // выполняем преобразование строки
Операция усечения выполняется в два этапа, сначала задается кодировка строки и только после этого выполняется усечение.
Кодировку достаточно указать только один раз, даже в случае применения нескольких функций.

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

Петрелевич Сергей
petrelevich@yandex.ru
www.SmartyIT.ru

Метки: PHP   UTF8   Web  

Комментарии.

Внимание.
Комментировать могут только зарегистрированные пользователи.
Возможно использование следующих HTML тегов: <a>, <b>, <i>, <br>.

Яндекс цитирования Ðåéòèíã@Mail.ru Rambler's Top100