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

Перегрузка функций PHP

Адаптивный дизайн. Делаем сайты для любых устройств своими руками
Web

Адаптивный дизайн. Делаем сайты для любых устройств своими руками

Web

Как получить имя переменной в виде строки в PHP?

Web

Как сделать списки HTML, какой из них называется неупорядоченным, как с ними работать

×