【问题标题】:How to convert Bytes(UTF-8) to Unicode in php?如何在 php 中将字节(UTF-8)转换为 Unicode?
【发布时间】:2015-07-20 08:39:15
【问题描述】:

如何转换

\xF0\x9F\x98\x83

\u1F603

在 php 中?

PS:这是一个表情符号 -> ????,我需要 Unicode 才能使用 Twemoji。

【问题讨论】:

  • UTF-8 is Unicode,你的问题没有意义。此外,您在那里提到的那些值,它们是转义序列,以不同的方式表示同一事物。
  • @UlrichEckhardt 抱歉,我的英语不好。请查看此链接:WordPress smilies_init()。我想将$wpsmiliestrans 的值转换为twemoji.maxcdn.com/36x36/2764.png

标签: php unicode utf-8 byte emoji


【解决方案1】:

有趣的是,PHP 的内容并不多。似乎有a promising post,但不幸的是,接受的答案在您的情况下给出了不正确的结果。

这里是用 PHP 重写的 Adam's solution 的修订版。

/**
 * Translates a sequence of UTF-8 bytes to their equivalent unicode code points.
 * Each code point is prefixed with "\u".
 *
 * @param string $utf8
 *
 * @return string
 */
function utf8_to_unicode($utf8) {
    $i = 0;
    $l = strlen($utf8);

    $out = '';

    while ($i < $l) {
        if ((ord($utf8[$i]) & 0x80) === 0x00) {
            // 0xxxxxxx
            $n = ord($utf8[$i++]);
        } elseif ((ord($utf8[$i]) & 0xE0) === 0xC0) {
            // 110xxxxx 10xxxxxx
            $n =
                ((ord($utf8[$i++]) & 0x1F) <<  6) |
                ((ord($utf8[$i++]) & 0x3F) <<  0)
            ;
        } elseif ((ord($utf8[$i]) & 0xF0) === 0xE0) {
            // 1110xxxx 10xxxxxx 10xxxxxx
            $n =
                ((ord($utf8[$i++]) & 0x0F) << 12) |
                ((ord($utf8[$i++]) & 0x3F) <<  6) |
                ((ord($utf8[$i++]) & 0x3F) <<  0)
            ;
        } elseif ((ord($utf8[$i]) & 0xF8) === 0xF0) {
            // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
            $n =
                ((ord($utf8[$i++]) & 0x07) << 18) |
                ((ord($utf8[$i++]) & 0x3F) << 12) |
                ((ord($utf8[$i++]) & 0x3F) <<  6) |
                ((ord($utf8[$i++]) & 0x3F) <<  0)
            ;
        } elseif ((ord($utf8[$i]) & 0xFC) === 0xF8) {
            // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
            $n =
                ((ord($utf8[$i++]) & 0x03) << 24) |
                ((ord($utf8[$i++]) & 0x3F) << 18) |
                ((ord($utf8[$i++]) & 0x3F) << 12) |
                ((ord($utf8[$i++]) & 0x3F) <<  6) |
                ((ord($utf8[$i++]) & 0x3F) <<  0)
            ;
        } elseif ((ord($utf8[$i]) & 0xFE) === 0xFC) {
            // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
            $n =
                ((ord($utf8[$i++]) & 0x01) << 30) |
                ((ord($utf8[$i++]) & 0x3F) << 24) |
                ((ord($utf8[$i++]) & 0x3F) << 18) |
                ((ord($utf8[$i++]) & 0x3F) << 12) |
                ((ord($utf8[$i++]) & 0x3F) <<  6) |
                ((ord($utf8[$i++]) & 0x3F) <<  0)
            ;
        } else {
            throw new \Exception('Invalid utf-8 code point');
        }

        $n = strtoupper(dechex($n));
        $pad = strlen($n) <= 4 ? strlen($n) + strlen($n) %2 : 0;
        $n = str_pad($n, $pad, "0", STR_PAD_LEFT);

        $out .= sprintf("\u%s", $n);
    }

    return $out;
}

在你的情况下

php > var_dump(utf8_to_unicode("\xF0\x9F\x98\x83"));
string(7) "\u1F603"

【讨论】:

  • 拜托,哦,拜托,叫它utf8_to_utf16。两者都是“Unicode”,因为两者都是 Unicode 代码点的表示。
  • @DarkDust 为什么是“utf16”?它不产生 UTF-16 代码单元。可以说它也不会产生 UTF-32,因为它不执行验证。
  • 我会为此建议一些其他名称(没有一个很好)。例如,它不验证连续字节,并且对于单个代码点最多接受六个字节,这两者都违反了 UTF-8。此外,输出肯定不是 UTF-16,因为这需要至少两个 16 位的字符来表示字符。我会说使用“iconv”会是一个更好的选择。
  • 我越看这个函数,WTF 越多。 \u escape sequence produces UTF-8 sequences。那么,这个函数接受一个 UTF-8 编码的字符并输出一个像 \u1234 这样的 string,当用作 printf 格式时,它又会评估为一个 UTF-8 序列?这有什么意义?
  • @DarkDust 它确实缺少一些文档并且命名已关闭。这个函数“试图”做的是将 UTF-8 编码的字符序列转换为它们各自的 literal unicode 代码点。不幸的是,我不知道\u 的特殊含义。请注意代码点 必须 如何用花括号括起来,以便 PHP 将其解释为代码点。因此,不幸的是,相似之处是巧合。该名称应该与utf8_to_literal_unicode_code_points 类似。
【解决方案2】:

使用以下组合:

  1. stripcslashes() 转换 \xFF 字节转义。
    这将产生一个 UTF-8 字符串,因为它最初看起来就是这样。

  2. json_encode() 将“?”转换回 \uFFFF Unicode 转义。
    如果这就是你想要的结果。 (您的问题中没有足够的上下文来说明。)

【讨论】:

  • 3Q。但它不会通过json_encode(stripcslashes("\xF0\x9F\x98\x83"))将“\xF0\x9F\x98\x83”转换为“\u1F603”,结果是“\ud83d\ude03”;在这个页面WordPress smilies_init()你可以找到一个数组->$wpsmiliestrans;我需要将值转换为 unicode,所以我可以创建一个图像链接,如“twemoji.maxcdn.com/36x36/2764.png”,2764 是 unicode 的一部分。对不起,我的英语不好。
猜你喜欢
  • 2015-10-08
  • 1970-01-01
  • 2011-06-05
  • 2021-07-06
  • 2012-06-20
  • 2014-05-22
  • 2013-01-25
  • 2013-06-20
  • 2012-07-02
相关资源
最近更新 更多