Статьи

Перевод Unicode в PHP с помощью Portable UTF-8

PHP позволяет многобайтовым именам переменных, таким как $a∩b$Ʃxy$Δxutf8_encode()utf8_decode() Тем не менее, общепризнанно, что PHP не поддерживает Unicode.

В этой статье рассказывается о том, что означает отсутствие поддержки Unicode, и демонстрируется использование библиотеки, которая обеспечивает поддержку Unicode для вашего PHP-приложения, Portable UTF-8.

Поддержка Unicode в PHP

Отсутствие в PHP поддержки Unicode / multibyte означает, что стандартные функции обработки строк обрабатывают строки как последовательность однобайтовых символов. Фактически, официальное руководство определяет строку в PHP как «последовательность символов, где символ совпадает с байтом». PHP поддерживает только 8-битные символы, в то время как Unicode (и многие другие наборы символов) могут требовать более один байт для представления символа. Это ограничение PHP затрагивает почти все аспекты манипуляции со строками, включая (но не ограничиваясь этим) извлечение подстроки, определение длины строки, разбиение строки, тасование и т. Д.

Усилия по решению этой проблемы начались в начале 2005 года, но работа по внедрению поддержки PHP в Unicode была остановлена ​​и отложена в 2010 году по нескольким причинам . Поскольку нативная поддержка Unicode в PHP может занять годы, если вообще когда-либо, разработчики должны полагаться на расширения, такие как mbstring и iconv, которые доступны, чтобы заполнить пробел, но которые предоставляют лишь ограниченную поддержку Unicode. Эти библиотеки не ориентированы на Unicode и способны также переводить кодировки не-Unicode. Они вносят позитивный вклад в попытку облегчить работу со строками Unicode.

Но вышеупомянутые расширения также имеют свои недостатки. Они предоставляют лишь ограниченную функциональность для обработки строк Unicode, и ни одна из них не включена по умолчанию. Администратор сервера должен явно включить любое или все расширения, чтобы сделать их доступными через приложения PHP. Поставщики виртуального хостинга часто усугубляют ситуацию, устанавливая одно или два расширения, что затрудняет разработчикам полагаться на постоянно доступный API для своих нужд Unicode.

Несмотря на все это, хорошо то, что PHP может выводить текст Unicode. Это потому, что PHP на самом деле не волнует, отправляем ли мы английский текст, закодированный в ASCII, или какой-то другой текст, принадлежащий языку, символы которого кодируются в несколько байтов. Зная это, разработчикам PHP сейчас нужен только API, обеспечивающий удобную обработку строк на основе Unicode.

Портативный UTF-8

Недавнее решение — создание библиотек пространства пользователя, написанных на PHP. Эти библиотеки могут быть легко связаны с приложением для обеспечения поддержки Unicode, даже если поддержка на уровне сервера / языка отсутствует. Многие приложения с открытым исходным кодом уже включают свои собственные такие библиотеки, и многие другие используют свободно доступные сторонние библиотеки; одна такая библиотека — Portable UTF-8 .

Portable UTF-8 — это бесплатная, легкая библиотека, созданная на основе mbstring и iconv. Он расширяет возможности двух расширений, предоставляя около 60 функций для работы со строками, тестирования и проверки на основе Unicode; он предлагает аналоги с поддержкой UTF-8 для почти всех обычных функций PHP для обработки строк. Как следует из названия, Portable UTF-8 использует UTF-8 в качестве основной схемы кодирования символов.

Библиотека использует доступные расширения (mbstring и iconv) по соображениям скорости и сглаживает некоторые несоответствия работы с ними напрямую, но отступает от процедур UTF-8, написанных на чистом PHP, если расширения недоступны на сервере , Portable-UT8 является полностью переносимым и работает с любой установкой PHP версии 4.2 или выше.

Обработка струн с помощью портативного UTF-8

Текстовый редактор с плохой поддержкой Unicode может повредить текст при чтении, а текст, скопированный из такого редактора и опубликованный в веб-форме, может стать источником недопустимого UTF-8 для вашего приложения. При работе с пользовательским вводом важно убедиться, что ввод именно то, что ожидает приложение. Чтобы определить, является ли текст допустимым UTF-8, мы можем использовать библиотечную is_utf8()

 if (is_utf8($_POST['title'])) {
    // do something...
}

Восстановление символов из недопустимых байтов является невозможным упражнением, поэтому вычеркнуть байты, которые не могут быть распознаны как допустимые символы UTF-8, может быть единственным вариантом. Мы можем удалить недопустимые байты с помощью функции utf8_clean()

 $title = utf8_clean($_POST['title']);

Каждый символ Unicode может быть закодирован в соответствующую сущность HTML, и вы можете захотеть закодировать текст таким образом, чтобы предотвратить атаки XSS перед его выводом в браузер.

 echo utf8_html_encode($title);

Распространены пробелы в начале и конце строки. Unicode перечисляет около 20 пробельных символов, и есть некоторые управляющие символы на основе ASCII, которые следует учитывать и для такой обрезки.

 $title = utf8_trim($title);

С другой стороны, в середине строки могут быть дубликаты таких пробелов, которые следует удалить. Ниже показано, как utf8_remove_duplicates()utf8_ws()

 $title = utf8_remove_duplicates($title, utf8_ws());

Традиционные решения для создания URL-слагов по причинам SEO используют транслитерацию и удаляют все символы, не входящие в ASCII, из слагов. Это делает URL менее ценным, чем могло бы быть. Хотя URL-адреса могут поддерживать символы в кодировке UTF-8, такой разборки или транслитерации не требуется, и мы можем создавать расширенные слагы, содержащие символы любого языка:

 $slug = utf8_url_slug($title, 30); // char length 30

Начиная с проверки входных данных и заканчивая сохранением данных в какой-либо базе данных, приложение с поддержкой Unicode фокусируется на символах и длине символа, а не на байтах и ​​длине байта. Это смещение фокуса требует нового интерфейса, который понимает разницу. Обычно вводят ограничение на длину вводимого символа, поэтому здесь мы создаем подстроку, если длина ввода превышает 60 символов.

 if (utf8_strlen($title) > 60) {
    $title  = utf8_substr($title, 0, 60);
}

Или в качестве альтернативы:

 if (!utf8_fits_inside($title , 60)) {
    $title  = utf8_substr($title, 0 ,60);
}

Существует три различных способа доступа к индивидуальному персонажу с помощью библиотеки Portable-UT8. Мы можем использовать utf8_access()

 echo 'The sixth character is: ' . utf8_access($string, 5);

utf8_chr_map()

 utf8_chr_map('some_callback', $string);

И мы можем разделить строку на массив символов с помощью utf8_split()

 array_map('some_callback', utf8_split($string));

Для работы с Unicode может также потребоваться найти минимальную / максимальную кодовую точку в строке, разделить строки, поработать с меткой порядка байтов, преобразовать регистр строк, рандомизировать / перестановить, заменить и т. Д. Все это поддерживается Portable-UT8.

Вывод

Разработка PHP 6 была остановлена, что привело к задержке столь необходимой нативной поддержки Unicode для разработки многоязычных приложений. Таким образом, в то же время серверные расширения и библиотеки пользовательского пространства, такие как Portable UTF-8, играют важную роль в оказании помощи разработчикам в создании более стандартизированной сети, соответствующей местным потребностям.