PHP построить строку Unicode? - PullRequest
7 голосов
/ 14 сентября 2010

С учетом десятичного или шестнадцатеричного числа Unicode для символа, который хочет быть выведен из PHP-скрипта CLI, как PHP может его сгенерировать? Кажется, что функция chr() не генерирует правильный вывод. Вот мой тестовый сценарий, использующий символ Разрыв раздела U + 00A7 (A7 в шестнадцатеричном, 167 в десятичном, должен быть представлен как C2 A7 в UTF-8) в качестве теста:

<?php
echo "Section sign: ".chr(167)."\n"; // Using CHR function
echo "Section sign: ".chr(0xA7)."\n";
echo "Section sign: ".pack("c", 0xA7)."\n"; // Using pack function?
echo "Section sign: §\n"; // Copy and paste of the symbol into source code

Вывод, который я получаю (через сеанс SSH на сервер):

Section sign: ?
Section sign: ?
Section sign: ?
Section sign: §

Итак, это доказывает, что в используемом мной терминальном шрифте есть символ Разрыв раздела, и SSH-соединение отправляет его успешно, но chr() не создает его должным образом при построении из кода ,

Если все, что у меня есть, это номер кода, а не опция копирования / вставки, какие варианты у меня есть?

Ответы [ 5 ]

5 голосов
/ 14 сентября 2010

Если у вас есть iconv, вот простой способ, который не требует самостоятельной реализации UTF-8:

function unichr($i) {
    return iconv('UCS-4LE', 'UTF-8', pack('V', $i));
}
4 голосов
/ 14 сентября 2010

PHP не знает Unicode при исключении функций mb_ и iconv. Вам придется самостоятельно кодировать UTF-8.

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

function codepointToUtf8($codepoint)
{
    if ($codepoint < 0x7F) // U+0000-U+007F - 1 byte
        return chr($codepoint);
    if ($codepoint < 0x7FF) // U+0080-U+07FF - 2 bytes
        return chr(0xC0 | ($codepoint >> 6)).chr(0x80 | ($codepoint & 0x3F);
    if ($codepoint < 0xFFFF) // U+0800-U+FFFF - 3 bytes
        return chr(0xE0 | ($codepoint >> 12)).chr(0x80 | (($codepoint >> 6) & 0x3F).chr(0x80 | ($codepoint & 0x3F);
    else // U+010000-U+10FFFF - 4 bytes
        return chr(0xF0 | ($codepoint >> 18)).chr(0x80 | ($codepoint >> 12) & 0x3F).chr(0x80 | (($codepoint >> 6) & 0x3F).chr(0x80 | ($codepoint & 0x3F);
}
3 голосов
/ 14 сентября 2010
chr

(PHP 4, PHP 5)

chr — Return a specific character

Report a bug
 Description

string chr ( int $ascii )
Returns a one-character string containing the character specified by ascii.

Эта функция дополняет ord ().

важно слово ascii :) попробуйте следующее:

  function uchr ($codes) {
        if (is_scalar($codes)) $codes= func_get_args();
        $str= '';
        foreach ($codes as $code) $str.= html_entity_decode('&#'.$code.';',ENT_NOQUOTES,'UTF-8');
        return $str;
    }
    echo "Section sign: ".uchr(167)."\n"; // Using CHR function
    echo "Section sign: ".uchr(0xA7)."\n";
3 голосов
/ 14 сентября 2010

Не забывайте, что UTF-8 - это кодировка переменной длины.

§ не входит в первые 128 (ASCII) символов, которые UTF-8 может отображать в один байт. § - это многобайтовый символ в UTF-8, которому предшествует c2 байт, который обозначает first byte of a two-byte sequence.. Это должно работать:

echo "Section sign: ".chr(0xC2).chr(0xA7)."\n"; 
0 голосов
/ 25 июня 2014

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

Ручное перепрограммирование ascii-to-unicode похоже на переизобретение колеса, не говоря об ошибках / потенциале производительности.

Лучшее решение, которое я нашел, было использовать:

  1. pack для создания значений из входных данных с использованием соответствующих кодов для получения нужного количества данных, обычно pack("H*", <input data>) для чтения из шестнадцатеричных значений
  2. mb_convert_encoding для преобразования строк ASCII в строки Unicode, используя mb_convert_encoding(<ASCII string>, "UTF-8"). Если входная строка не распознается должным образом, третий параметр этой функции позволяет указать входную кодировку
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...