如何在PHP中将Unicode NCR表单转换为其原始形式?

时间:2009-10-20 07:51:33

标签: php unicode fpdf cjk

为避免“怪物角色”,我选择Unicode NCR表格将非英文字符存储在数据库(MySQL)中。然而,我使用的PDF插件(FPDF)不接受Unicode NCR格式作为正确的格式;它直接显示数据:

這個一個例子

但我希望它显示如下:

这个一个例子

有没有方法可以将Unicode NCR格式转换为原始格式?

P.S。句子的意思是繁体中文中的“这是一个例子”。

P.S。我知道NCR形式浪费了存储空间,但它是存储非英文字符最安全的方法。如果我错了,请纠正我。感谢。

3 个答案:

答案 0 :(得分:3)

使用PHP mbstring扩展有一个更简单的解决方案。

// convert any Decimal NCRs to Unicode characters
$string = "這個一個例子";
$output = preg_replace_callback(
  '/(&#[0-9]+;)/u', 
  function($m){
    return utf8_entity_decode($m[1]);
  }, 
  $string
);
echo $output; // 這個一個例子

//callback function for the regex
function utf8_entity_decode($entity){
  $convmap = array(0x0, 0x10000, 0, 0xfffff);
  return mb_decode_numericentity($entity, $convmap, 'UTF-8');
}

' utf8_entity_decode'函数来自PHP.net(Andrew Simpson):http://php.net/manual/ru/function.mb-decode-numericentity.php#48085。我稍微修改了代码,以避免使用正则表达式中已弃用的' - 修饰符。

答案 1 :(得分:1)

解决方案非常复杂。

解决方案有3个部分: 第1部分:安装FPDF中文插件 第2部分:将NCR格式转换为UTF-8 第3部分:将UTF-8格式转换为BIG5(或任何目标编码)

第1部分

我从这里获取了FPDF中文插件:http://dev.xoofoo.org/modules/content/d1/d6e/a00073.html 它用于在FPDF中显示中文字符,并获取所需的所有中文字体。要安装此插件,只需将其包含在PHP中即可。 (但对于我的情况,我使用另一个名为CellPDF的插件,它与这个中文插件崩溃;因此,我必须合并代码并解决冲突)

第2部分

要将NCR格式转换为UTF-8,我使用以下代码:

function html_entity_decode_utf8($string)
{
    static $trans_tbl;

    // replace numeric entities
    $string = preg_replace('~&#x([0-9a-f]+);~ei', 'code2utf(hexdec("\\1"))', $string);
    $string = preg_replace('~&#([0-9]+);~e', 'code2utf(\\1)', $string);

    // replace literal entities
    if (!isset($trans_tbl))
    {
        $trans_tbl = array();

        foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key)
            $trans_tbl[$key] = utf8_encode($val);
    }

    return strtr($string, $trans_tbl);
}
function code2utf($num)
{
    if ($num < 128) return chr($num);
    if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
    if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
    if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
    return '';
}

由php.net上的laurynas butkus编写(链接:http://www.php.net/manual/en/function.html-entity-decode.php) 虽然这段代码本身将NCR格式转换为“怪物角色”,但我知道这是一个好的开始。

第3部分

在深入挖掘php.net后,我找到了一个很好的函数:iconv,用于转换编码。 所以我用以下函数包装上面的代码:

function ncr_decode($string, $target_encoding='BIG5') {
    return iconv('UTF-8', 'BIG5', html_entity_decode_utf8($string));
}

因此,如果我想转换前一行NCR字符串,我只需要运行此函数:

ncr_decode("&#36889;&#20491;&#19968;&#20491;&#20363;&#23376;");

P.S。默认情况下,我将目标编码设置为BIG5。

就是这样!

答案 2 :(得分:0)

看看html_entity_decode

PS:更好的方法是一直使用UTF-8。在SO上搜索有关PHP,MySQL和UTF-8的问题,有一些列出了可能存在的问题。