如何用php显示汉字的utf-8和unicode值?

How to display the utf-8 and unicode value of chinese character with php?

在python中,我可以得到一个utf-8内容和汉字的Unicode。

python version 3.4
>>> print("你".encode("utf-8"))
b'\xe4\xbd\xa0'
>>> print("你".encode("unicode-escape"))
b'\u4f60'

如何显示 的 utf-8 和 unicode 值(表示你是英文的) 在网络中使用 php?如何使用 php 在 Firefox 中获得与使用 python 相同的输出 '\xe4\xbd\xa0'\u4f60

第一个例子是显示utf-8编码的字节;因此,假设字符串是 utf-8 编码的,您可以简单地打印每个字符的十六进制 ACSII 值。

$str = "你";

foreach (str_split($str) as $byte) {
    echo '\x'.str_pad(dechex(ord($byte)), 2, '0', STR_PAD_LEFT);
}

// prints: \xe4\xbd\xa0

第二行打印字符的 Unicode code point。由于 php 字符串只是单字节,我们必须先解码字节以访问代码点,然后格式化十六进制数。

基于 WHATWG Encoding Standard we can make a utf-8 decoder to decode code points including supplementary code points.

// Decodes a utf-8 encoded string and returns an array
// of code points or null if there was an error
// https://encoding.spec.whatwg.org/#utf-8-decoder
function decode_utf8($str)
{
    $code_point = 0;
    $bytes_needed = 0;
    $bytes_seen = 0;

    $lower_boundary = 0x80;
    $upper_boundary = 0xbf;

    $code_points = array();

    for ($i = 0, $len = strlen($str); $i < $len; $i++) {
        $byte = ord($str[$i]);

        if ($bytes_needed == 0) {
            if ($byte >= 0x00 and $byte <= 0x7f) {
                $code_points[] = $byte;
            } elseif ($byte >= 0xc2 and $byte <= 0xdf) {
                $bytes_needed = 1;
                $code_point = $byte - 0xc0;
            } elseif ($byte >= 0xe0 and $byte <= 0xef) {
                if ($byte == 0xe0) {
                    $lower_boundary = 0xa0;
                }
                if ($byte == 0xed) {
                    $upper_boundary = 0x9f;
                }

                $bytes_needed = 2;
                $code_point = $byte - 0xe0;
            }  elseif ($byte >= 0xf0 and $byte <= 0xf4) {
                if ($byte == 0xf0) {
                    $lower_boundary = 0x90;
                }
                if ($byte == 0xf4) {
                    $upper_boundary = 0x8f;
                }

                $bytes_needed = 3;
                $code_point = $byte - 0xf0;
            }  else {
                return;
            }

            $code_point = $code_point << (6 * $bytes_needed);
            continue;
        }

        if ($byte < $lower_boundary or $byte > $upper_boundary) {
            return;
        }

        $lower_boundary = 0x80;
        $upper_boundary = 0xbf;

        $bytes_seen++;
        $code_point += ($byte - 0x80) << (6 * ($bytes_needed - $bytes_seen));

        if ($bytes_seen != $bytes_needed) {
            continue;
        }

        $code_points[] = $code_point;

        $code_point = 0;
        $bytes_needed = 0;
        $bytes_seen = 0;
    }

    if ($bytes_needed != 0) {
        return;
    }

    return $code_points;
}

解码代码点后,我们使用 dechex 将它们转换为十六进制。然后,使用 str_pad,我们用零填充它们。如果代码点在基本的多语言纯文本中,我们将其填充为四个字符长,否则我们将其设置为六个字符长。最后,我们在开头加上 \u

$str = '你';

foreach (decode_utf8($str) as $code_point) {
    echo '\u'.str_pad(dechex($code_point), $code_point>0xffff?6:4, '0', STR_PAD_LEFT);
}
// prints: \u4f60

它也适用于基本多语言普通字符之外的字符,例如 CJK Ideograph Extensions

$str = ''; // U+020000

foreach (decode_utf8($str) as $code_point) {
    echo '\u'.str_pad(dechex($code_point), $code_point>0xffff?6:4, '0', STR_PAD_LEFT);
}
// prints: \u020000