使用mbstring将PHP中的Unicode引用转换为UTF-8字符

使用mbstring将PHP中的Unicode引用转换为UTF-8字符,php,encoding,utf-8,character-encoding,mbstring,Php,Encoding,Utf 8,Character Encoding,Mbstring,我在数据库中有一组数据,这些数据是用unicode字符输入的,但它们被解释为字符串。也就是说,应该有一个撇号”我实际上得到了\u2019 因此,我现在需要将其转换为字符表示形式,即“。首先,很容易将字符串更改为其实体版本:’,然后我需要将其转换为正确的UTF-8多字节字符串 我尝试了很多方法来做到这一点;在本地服务器上,我可以使用preg_match函数提取字符,然后将每个字符传递给以下函数: mb_convert_encoding($string, "UTF-8", "HTML-E

我在数据库中有一组数据,这些数据是用unicode字符输入的,但它们被解释为字符串。也就是说,应该有一个撇号
我实际上得到了
\u2019

因此,我现在需要将其转换为字符表示形式,即
。首先,很容易将字符串更改为其实体版本:
,然后我需要将其转换为正确的UTF-8多字节字符串

我尝试了很多方法来做到这一点;在本地服务器上,我可以使用preg_match函数提取字符,然后将每个字符传递给以下函数:

mb_convert_encoding($string, "UTF-8", "HTML-ENTITIES");
听起来很有道理,而且没有问题。在浏览器中关闭UTF-8字符集表明这实际上已转换为
€™由浏览器读取时的默认编码

但是,在我的生产环境中运行的完全相同的代码在呈现为UTF-8时会生成可怕的“缺少符号”框。关闭UTF-8,它会生成任何呈现为
ò°”
的字节流。它似乎输出4个字节而不是3个字节,我不知道这是否相关,因为我对字符编码没有很好的理解

我假设问题在于我的mbstring设置。以下是我的本地服务器上的mbstring设置:

Multibyte Support   enabled
Multibyte string engine libmbfl
HTTP input encoding translation disabled
Multibyte (japanese) regex support  enabled
Multibyte regex (oniguruma) version 4.7.1
mbstring.detect_order   no value    no value
mbstring.encoding_translation   Off Off
mbstring.func_overload  0   0
mbstring.http_input auto    auto
mbstring.http_output    UTF-8   UTF-8
mbstring.http_output_conv_mimetypes ^(text/|application/xhtml\+xml)^(text/|application/xhtml\+xml)
mbstring.internal_encoding  UTF-8   UTF-8
mbstring.language   neutral neutral
mbstring.strict_detection   Off Off
mbstring.substitute_character   no value    no value
我的生产环境有一些不同之处:

Multibyte Support   enabled
Multibyte string engine libmbfl
Multibyte (japanese) regex support  enabled
Multibyte regex (oniguruma) version 3.7.1
mbstring.detect_order   no value    no value
mbstring.encoding_translation   Off Off
mbstring.func_overload  0   0
mbstring.http_input auto    auto
mbstring.http_output    UTF-8   UTF-8
mbstring.internal_encoding  UTF-8   UTF-8
mbstring.language   neutral neutral
mbstring.strict_detection   Off Off
mbstring.substitute_character   no value    no value

有人知道我做错了什么吗?

看看这是否能帮助你:

于2012年9月19日添加:

function ascii2hex($ascii)
{
    $hex = '';
    for ($i = 0; $i < strlen($ascii); $i++)
    {
        $byte = strtoupper(dechex(ord($ascii{$i})));
        $byte = str_repeat('0', 2 - strlen($byte)).$byte;
        $hex .= $byte." ";
    }
    return $hex;
}

function hex2ascii($hex)
{
    $ascii = '';
    $hex = str_replace(" ", "", $hex);
    for($i = 0; $i < strlen($hex); $i = $i+2)
        $ascii .= chr(hexdec(substr($hex, $i, 2)));

    return($ascii);
}
函数ascii2hex($ascii) { $hex=''; 对于($i=0;$i
看看这是否能帮助您:

于2012年9月19日添加:

function ascii2hex($ascii)
{
    $hex = '';
    for ($i = 0; $i < strlen($ascii); $i++)
    {
        $byte = strtoupper(dechex(ord($ascii{$i})));
        $byte = str_repeat('0', 2 - strlen($byte)).$byte;
        $hex .= $byte." ";
    }
    return $hex;
}

function hex2ascii($hex)
{
    $ascii = '';
    $hex = str_replace(" ", "", $hex);
    for($i = 0; $i < strlen($hex); $i = $i+2)
        $ascii .= chr(hexdec(substr($hex, $i, 2)));

    return($ascii);
}
函数ascii2hex($ascii) { $hex=''; 对于($i=0;$i
我想你要找的是多字节版本的
ord
chr

为此,我写了以下
polyfill

if (!function_exists('mb_internal_encoding')) {
    function mb_internal_encoding($encoding = NULL) {
        return ($from_encoding === NULL) ? iconv_get_encoding() : iconv_set_encoding($encoding);
    }
}

if (!function_exists('mb_convert_encoding')) {
    function mb_convert_encoding($str, $to_encoding, $from_encoding = NULL) {
        return iconv(($from_encoding === NULL) ? mb_internal_encoding() : $from_encoding, $to_encoding, $str);
    }
}

if (!function_exists('mb_chr')) {
    function mb_chr($ord, $encoding = 'UTF-8') {
        if ($encoding === 'UCS-4BE') {
            return pack("N", $ord);
        } else {
            return mb_convert_encoding(mb_chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE');
        }
    }
}

if (!function_exists('mb_ord')) {
    function mb_ord($char, $encoding = 'UTF-8') {
        if ($encoding === 'UCS-4BE') {
            list(, $ord) = (strlen($char) === 4) ? @unpack('N', $char) : @unpack('n', $char);
            return $ord;
        } else {
            return mb_ord(mb_convert_encoding($char, 'UCS-4BE', $encoding), 'UCS-4BE');
        }
    }
}

演示 输出:

Get string from numeric DEC value
string(3) "我"
string(3) "好"

Get string from numeric HEX value
string(3) "我"
string(3) "好"

Get numeric value of character as DEC string
int(25105)
int(22909)

Get numeric value of character as HEX string
string(4) "6211"
string(4) "597d"

我想你要找的是多字节版本的
ord
chr

为此,我写了以下
polyfill

if (!function_exists('mb_internal_encoding')) {
    function mb_internal_encoding($encoding = NULL) {
        return ($from_encoding === NULL) ? iconv_get_encoding() : iconv_set_encoding($encoding);
    }
}

if (!function_exists('mb_convert_encoding')) {
    function mb_convert_encoding($str, $to_encoding, $from_encoding = NULL) {
        return iconv(($from_encoding === NULL) ? mb_internal_encoding() : $from_encoding, $to_encoding, $str);
    }
}

if (!function_exists('mb_chr')) {
    function mb_chr($ord, $encoding = 'UTF-8') {
        if ($encoding === 'UCS-4BE') {
            return pack("N", $ord);
        } else {
            return mb_convert_encoding(mb_chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE');
        }
    }
}

if (!function_exists('mb_ord')) {
    function mb_ord($char, $encoding = 'UTF-8') {
        if ($encoding === 'UCS-4BE') {
            list(, $ord) = (strlen($char) === 4) ? @unpack('N', $char) : @unpack('n', $char);
            return $ord;
        } else {
            return mb_ord(mb_convert_encoding($char, 'UCS-4BE', $encoding), 'UCS-4BE');
        }
    }
}

演示 输出:

Get string from numeric DEC value
string(3) "我"
string(3) "好"

Get string from numeric HEX value
string(3) "我"
string(3) "好"

Get numeric value of character as DEC string
int(25105)
int(22909)

Get numeric value of character as HEX string
string(4) "6211"
string(4) "597d"

伟大的将一些图标提取到imagegd.great时,mb_chr工作正常。将某些图标提取到imagegd时,mb_chr工作正常。