Unicode для практикующих PHP-программистов (исходники)Источник: IBM developerWorks Россия Кэмерон Лэйрд
При правильном подходе PHP эффективно обрабатывает не только иногда встречающиеся в английских именах и заимствованиях акцентированные символы, но и символы из других самых распространенных языков: немецкого, русского, китайского, японского и многих других. Выполните эту небольшую PHP-программу: Листинг 1. Кодирование вывода информации на русском языке
Если все прошло удачно, вы увидите слово Здравствуйте - "Hello" или "Greetings" на русском языке.
Слишком часто работа в PHP с символами, отличными от стандартного английского алфавита, является делом везения или даже волшебства. Несмотря на то, что проделана огромная работа в таких областях как кодирование символов, интернационализация и т.д., большая ее часть сделана неправильно, или как минимум устарела, и очень многое зависит от конкретной конфигурации PHP. Целью данной статьи является представление всего лишь основ обработки Unicode в PHP, но это делается с достаточной аккуратностью и полнотой, что обеспечивает прочную основу для любого "интернационального программирования", которое нужно выполнить. Очень многое происходит за кулисамиЭта очевидно простая программа из двух строк содержит очень много допущений. Прежде всего, я предполагаю использование PHP V5. Хотя можно работать с не английскими символами и на PHP V4, обычно это предполагает вовлечение не стандартных расширений, что определенно не уместно в 2007 году. В PHP V6, с другой стороны, планируется решить так много проблем кодирования символов, что это делает не нужными все методики, приведенные в данной статье. Есть надежда, что Unicode-строки в PHP V6 будут просто работать. Даже при стандартной процедуре установки PHP V5 нет гарантий, что вы увидите те же результаты, которые вижу я. Во время разработки я попробовал несколько браузеров, которые не воспринимали русские шрифты и, следовательно, представляли информацию в латинской транслитерации: Формат кодаИсходный код на PHP в данной статье должен работать у подавляющего большинства разработчиков. Он применим (насколько это было возможно сделать) к любой стандартной установке PHP V5. Чтобы сконцентрироваться на главном, исходный код представлен без стандартных охватывающих код тегов Листинг 2. Кодирование вывода информации на русском языке с более полным применением тегов
PHP V5 и стандартные установки браузеров охватывают подавляющее большинство возможных ситуаций. Почти все описанные ниже практические методики применимы к любой конфигурации php.ini , locale , набору шрифтов и т.д.
Предположим, что имеется совместимая платформа для наших экспериментов. Что мы с ней делаем ? В большинстве случаев следующее:
Давайте посмотрим, что это влечет за собой. Две проблемыЕсть две трудности. Для преодоления ограничений стандартного английского алфавита, даже для поддержки акцентированных символов, иногда встречающихся в правильно оформленном английском ("Ramon," "Godel," "aperitif"), корректным решением для наших целей является Unicode, закодированный как UTF-8. Даже если вы знакомы с Unicode, это не простая тема со сложными специализированными определениями, включающими "glyph" (графический элемент), "code point" (элемент кода), "abstract character" (абстрактный символ) и многое другое. Разработка с использованием Unicode имеет все ту же проблему "начальной настройки", типичную для сетевого программирования, и даже еще хуже - вместо рабочего сервера и клиента, необходимых для приемлемого отображения результатов, эффективному Unicode-программированию требуются:
Если вы много работаете с интернациональными проектами, то, возможно, используете специальные клавиатуры, редакторы, шрифты и т.д., для того чтобы можно было увидеть результаты работы. Второй главной трудностью программирования такого рода является то, что PHP не работает с Unicode. Вернее, не работал . Он изначально не предназначался для работы с символами, не входящими в таблицу ASCII. PHP V6 должен исправить этот недостаток и поднять PHP на уровень таких языков как Python, в котором в строки можно напрямую встраивать Unicode-данные. Между тем, Unicode-программирование с PHP требует осторожности и внимания. На многих форумах и в нескольких книгах по PHP, в которых упоминается Unicode, даются советы, полезные только с необычными расширениями, или предоставляются примеры кода, работающие только в некоторых конфигурациях. Это одна из причин того, что данная статья началась с листинга 1 - Этот же вывод можно закодировать даже более компактно:
Однако в таком виде сам исходный код не является "чистым" семи- или даже восьмибитовым, и многие редакторы, системы управления конфигурациями и другие инструментальные средства разработки, вероятно, исказят его. Одним из последствий может стать упомянутая выше загадка: будет или не будет работать программа? Еще один вариант, о котором стоит упомянуть:
Это ценная альтернатива листингу 1 для тех случаев, когда кто-то работает с таблицей Unicode-символов, выраженной в шестнадцатеричном, а не в десятичном формате. Возможности PHPВсе, кроме самых понятных манипуляций с Unicode, я оформляю в удобных функциях, приведенных в листинге 3. Результаты работы приведены в листинге 4. Листинг 3. Преобразование между отображаемыми UTF-8 и отлаживаемыми Unicode-кодами
Листинг 4. Результаты работы листинга 3
Обратите внимание на то, что весь исходный код и все, выводимое из строки на русском языке, отображается нормально и, на самом деле, является семибитовым ASCII, который легко копировать, отправлять по электронной почте и обрабатывать в обычных инструментальных средствах разработки. Еще один способ вывести это же русское слово:
Обратите внимание на то, что поскольку ваши данные находятся на одной машине, допустимо пропустить первое целое значение 65279, маркер порядка байтов (Byte Order Marker - BOM). BOM документирован как аспект Unicode, не специфичный для PHP, и здесь упоминаться не будет. Все это элементарные действия, очевидные для любого опытного PHP-программиста. Но их стоит описать явно, поскольку многое из того, что уже написано о PHP, является не понятным и не переносимым. Все другие толкования Unicode для PHP, которые я нашел разумными, рассматривают PHP как механизм перемещения символов из одного места в другое. Акцент делается на перемещении Unicode с клавиатуры в базу данных и на экран, поэтому нет необходимости проверять, как строки выглядят в самом PHP. Это, несомненно, упрощает код, и для окончательных форм ваших рабочих приложений могут никогда не понадобиться HTML-объекты или преобразования UTF-32. Но я считаю эти низкоуровневые приемы работы бесценными для всех случаев, когда программирование не проходит гладко - например, когда база данных и ваш XML-редактор не понимают кодировки, и вы видите только символы "????????". В таких ситуациях очень помогает работа с отдельными символами в их различных читабельных для человека интерпретациях. Соображения по программированиюКак уже упоминалось, PHP-работу с Unicode можно выполнить несколькими способами, включая расширения PHP, различные кодировки, и т.д. Но пока вы не стали экспертом в данной области, я не рекомендую пробовать принимать решение выбирать из этих многочисленных возможностей. Вы почти определенно достигнете наилучших результатов, если сконцентрируетесь на следующем:
Функция ellipsis, которую я часто использую, представляет маленький пример работы с многобайтными строковыми функциями. Оригинальной версией этой функции была:
Если использовать ее для long explanation и указать длину 10, возвратится long … , а при увеличении длины до 30 возвратится оригинальная строка. Это удобно, например, для быстрого создания аббревиатуры заголовков.
Ниже приведен пример более хитрого Unicode-решения. Листинг 6. Более продвинутый ellipses
Здесь используется стандартное оформление для многоточия, и корректно подсчитываются символы строки для аббревиации во всех комбинациях конфигураций PHP. Все эти элементы - только отправная точка для Unicode-программирования. Остается множество более сложных проблем:
Эти проблемы являются общими для большинства понимающих Unicode вычислительных языков. Цель данной статьи - предоставить информацию, для того чтобы вы понимали основы достаточно глубоко и были готовы перейти к более продвинутым темам. Помните: если обработка Unicode выполняется у вас большим по объему или замысловатым кодом, возможно, вы делаете что-то не так. PHP V5 и приведенные выше советы должны помочь упростить программирование Unicode. ЗаключениеЛюбой разработчик, прочитавший это введение и постигший основы, сможет программировать Unicode в PHP V5. Это не должно быть таинством. |