Web

Как использовать символы Юникода в PHP строках

Этот вопрос выглядит до безобразия простым, но я не смог найти на него ответ. Какой PHP-эквивалент следующей строки кода C#?

string str = "\u1000";

 Этот пример создает строку с одним символом Unicode, «числовое значение Unicode» которого равно 1000 в шестнадцатеричной системе (4096 в десятичной). То есть как в PHP создать строку с одним символом Unicode, «числовое значение Unicode» которого известно заранее?

 

Ответ 1

В PHP 7.0.0 появился синтаксис «Unicode codepoint escape». Теперь можно легко писать символы Unicode, используя строку с двойными кавычками или heredoc без вызова какой-либо функции.

$unicodeChar = "\u{1000}";

 

Ответ 2

Поскольку JSON напрямую поддерживает синтаксис \uxxxx, первое, что приходит мне в голову, это:

$unicodeChar = '\u1000';

echo json_decode('"'.$unicodeChar.'"');

 Другим вариантом может быть использование mb_convert_encoding():

echo mb_convert_encoding('က', 'UTF-8', 'HTML-ENTITIES');

 или использовать прямое сопоставление между UTF-16BE (big endian) и кодовой точкой Unicode:

echo mb_convert_encoding("\x10\x00", 'UTF-8', 'UTF-16BE');

 

Ответ 3

Интересно, почему никто еще не упомянул об этом, но вы можете сделать почти эквивалентную версию, используя экранирующие последовательности в строках с двойными кавычками:

\x[0-9A-Fa-f]{1,2}

 Последовательность символов, соответствующая регулярному выражению, является символом в шестнадцатеричной системе счисления. Пример ASCII:

<?php

    echo("\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21");

?>

 Вывод:

Hello World!

 Поэтому для вашего случая все, что вам нужно сделать, — это $str = "\x30\xA2";. Но это байты, а не символы. Байтовое представление кодовой точки Unicode совпадает с UTF-16 big endian, поэтому мы могли бы вывести их непосредственно в таком виде:

<?php

    header('content-type:text/html;charset=utf-16be');

    echo("\x30\xA2");

?>

 Вывод:

Если вы используете другую кодировку, вам нужно соответствующим образом изменить байты (в основном это делается с помощью библиотеки, но возможно и вручную). Пример UTF-16 little endian:

<?php

    header('content-type:text/html;charset=utf-16le');

    echo("\xA2\x30");

?>

Пример в формате UTF-8:

<?php

    header('content-type:text/html;charset=utf-8');

    echo("\xE3\x82\xA2");

?>

Есть также функция упаковки, но вы можете ожидать, что она будет медленной.

 

Ответ 4

PHP не знает этих управляющих последовательностей Unicode. Но поскольку неизвестные управляющие последовательности остаются незатронутыми, вы можете написать собственную функцию, которая преобразует такие управляющие последовательности Unicode:

function unicodeString($str, $encoding=null) {

    if (is_null($encoding)) $encoding = ini_get('mbstring.internal_encoding');

    return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/u', create_function('$match', 'return mb_convert_encoding(pack("H*", $match[1]), '.var_export($encoding, true).', "UTF-16BE");'), $str);

}

 Или с помощью выражения анонимной функции вместо create_function:

function unicodeString($str, $encoding=null) {

    if (is_null($encoding)) $encoding = ini_get('mbstring.internal_encoding');

    return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/u', function($match) use ($encoding) {

        return mb_convert_encoding(pack('H*', $match[1]), $encoding, 'UTF-16BE');

    }, $str);

}

 Его использование:

$str = unicodeString("\u1000");

 

 Ответ 5

Как уже упоминалось другими, PHP 7 вводит поддержку синтаксиса \u Unicode напрямую.

Как также упоминалось другими, единственный способ получить строковое значение из любого разумного описания символов Unicode в PHP это преобразовать его из чего-то другого (например, парсинг JSON, парсинг HTML или какой-то другой формы). Но это сопряжено с затратами производительности во время выполнения. Однако есть еще один вариант. Вы можете закодировать символ непосредственно в PHP с помощью \x двоичной экранировки. Синтаксис экранирования \x поддерживается и в PHP 5.

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

 Сначала пример доказательства:

// Unicode Character 'HAIR SPACE' (U+200A)

$htmlEntityChar = "&#8202;";

$realChar = html_entity_decode($htmlEntityChar);

$phpChar = "\xE2\x80\x8A";

echo 'Proof: ';

var_dump($realChar === $phpChar); // bool(true)

 Обратите внимание, что, как упоминалось в другом ответе, этот двоичный код уникален для конкретной кодировки символов. В приведенном выше примере \xE2\x80\x8A — это двоичный код для U+200A в UTF-8. Следующий вопрос: как перейти от U+200A к \xE2\x80\x8A?

Ниже приведен PHP-скрипт для генерации escape-последовательности для любого символа на основе JSON-строки, HTML-сущности или любого другого метода после того, как вы получите его в виде собственно строки.

function str_encode_utf8binary($str) {

    /** @author Krinkle 2018 */

    $output = '';

    foreach (str_split($str) as $octet) {

        $ordInt = ord($octet);

        // Convert from int (base 10) to hex (base 16), for PHP \x syntax

        $ordHex = base_convert($ordInt, 10, 16);

        $output .= '\x' . $ordHex;

    }

    return $output;

}

 

function str_convert_html_to_utf8binary($str) {

    return str_encode_utf8binary(html_entity_decode($str));

}

function str_convert_json_to_utf8binary($str) {

    return str_encode_utf8binary(json_decode($str));

}

 

// Пример для необработанной строки: Символ Юникода 'INFINITY' (U+221E)

echo str_encode_utf8binary('∞') . "\n";

// \xe2\x88\x9e

 

// Пример для HTML: Символ Юникода 'HAIR SPACE' (U+200A)

echo str_convert_html_to_utf8binary('&#8202;') . "\n";

// \xe2\x80\x8a

 

// Пример для JSON: символ Юникода 'HAIR SPACE' (U+200A)

echo str_convert_json_to_utf8binary('"\u200a"') . "\n";

// \xe2\x80\x8a

 

Схожие статьи

Web

Что это — stdin, stdout и stderr?

Как добавить сайт в каталог Dmoz.org, насколько просто туда попасть
Web

Как добавить сайт в каталог Dmoz.org, насколько просто туда попасть

Web

Почему json_encode возвращает пустую строку

Web

Как отсортировать многомерный массив по некоторому значению?

×