【问题标题】:Print Unicode characters PHP打印 Unicode 字符 PHP
【发布时间】:2013-07-09 03:29:23
【问题描述】:

我有一个数据库,它存储带有 Unicode 字符的视频游戏名称,但我不知道在将这些 Unicode 字符打印到 HTML 响应时如何正确转义它们。

例如,当我打印所有名称为 Uncharted 的游戏时,我会得到:

Uncharted: Drake's Fortuneâ„¢
Uncharted 2: Among Thievesâ„¢
Uncharted 3: Drake's Deceptionâ„¢

但它应该显示这个:

Uncharted: Drake's Fortune™
Uncharted 2: Among Thieves™
Uncharted 3: Drake's Deception™

我运行了一个快速的 JavaScript 转义函数来查看 ™ 是哪个 Unicode 字符,发现它是 \u2122。

如果我能让™ 字符正确显示,我完全转义字符串中的每个字符就没有问题。我的猜测是以某种方式找到字符串中每个字符的十六进制表示,并让 PHP 像这样渲染 Unicode 字符:

print "&#x2122";

请指导我了解 Unicode 转义字符串以实现 HTML 友好的最佳方法。不久前我为 JavaScript 做过类似的事情,但是 JavaScript 有一个用于转义和取消转义的内置函数。

我不知道任何类似功能的 PHP 函数。我读过ord 函数,但它只返回给定字符的ASCII 字符代码,因此™ 或™ 的显示不正确。我希望这个函数足够通用,可以应用于任何包含有效 Unicode 字符的字符串。

【问题讨论】:

    标签: php unicode html-escape-characters


    【解决方案1】:

    您的内部似乎有 UTF-8 编码的字符串,PHP 正确输出它们,但您的浏览器无法自动检测编码(它决定使用 ISO 8859-1 或其他编码)。

    最好的方法是通过发送相应的 HTTP 标头告诉浏览器正在使用 UTF-8:

    header("content-type: text/html; charset=UTF-8");  
    

    然后,您可以将其余代码保持原样,而不必对实体进行 html 编码或创建其他混乱。

    如果需要,您可以另外使用<meta>标签在生成的HTML中声明编码:

    • <meta http-equiv=Content-Type content="text/html; charset=UTF-8"> 用于 HTML
    • <meta charset="UTF-8"> 用于 HTML5

    HTTP 标头优先于<meta> 标记,但如果将 HTML 保存为 HD 然后在本地读取,则后者可能很有用。

    【讨论】:

    • @ViktorJoras 检查您的 PHP 脚本和/或服务器端字符串资源是否采用 UTF-8 编码。
    【解决方案2】:

    我花了很多时间试图找到更好的方法来打印 unicode 代码的等效字符,但我发现的方法不起作用或者非常复杂。

    也就是说,JSON 能够使用语法“\u[unicode_code]”来表示 unicode 字符,那么:

    echo json_decode('"\u00e1"'); 
    

    将打印等效的 unicode char,在这种情况下:á。

    P.D.注意单引号和双引号。如果你不把这两个都放上去,那是行不通的。

    【讨论】:

      【解决方案3】:

      试试这个:

      echo htmlentities("Uncharted: Drakes Fortune™ \n", ENT_QUOTES, "UTF-8");
      

      发件人:http://php.net/htmlentities

      【讨论】:

        【解决方案4】:
        // PHP 7.0
        var_dump(
            IntlChar::chr(0x2122),
            IntlChar::chr(0x1F638)
        );
        
        var_dump(
            utf8_chr(0x2122),
            utf8_chr(0x1F638)
        );
        
        function utf8_chr($cp) {
        
            if (!is_int($cp)) {
                exit("$cp is not integer\n");
            }
        
            // UTF-8 prohibits characters between U+D800 and U+DFFF
            // https://tools.ietf.org/html/rfc3629#section-3
            //
            // Q: Are there any 16-bit values that are invalid?
            // http://unicode.org/faq/utf_bom.html#utf16-7
        
            if ($cp < 0 || (0xD7FF < $cp && $cp < 0xE000) || 0x10FFFF < $cp) {
                exit("$cp is out of range\n");
            }
        
            if ($cp < 0x10000) {
                return json_decode('"\u'.bin2hex(pack('n', $cp)).'"');
            }
        
            // Q: Isn’t there a simpler way to do this?
            // http://unicode.org/faq/utf_bom.html#utf16-4
            $lead = 0xD800 - (0x10000 >> 10) + ($cp >> 10);
            $trail = 0xDC00 + ($cp & 0x3FF);
        
            return json_decode('"\u'.bin2hex(pack('n', $lead)).'\u'.bin2hex(pack('n', $trail)).'"');
        }
        

        【讨论】:

          猜你喜欢
          • 2018-06-22
          • 2013-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-23
          • 2014-08-01
          相关资源
          最近更新 更多