使用PHP的intl(ICU)功能检查有效的字符串编码

时间:2011-07-08 15:53:30

标签: php unicode icu

使用PHP的 intl 包装器中当前可用的功能,您将如何检查字符串编码的有效性? (例如检查有效的UTF-8)

我知道可以使用mbstring,iconv()和PCRE完成,但我对此问题特别感兴趣。

2 个答案:

答案 0 :(得分:2)

自PHP 5.5以来可以使用UConverter。手册不存在。有关API,请参阅https://wiki.php.net/rfc/uconverter

function replace_invalid_byte_sequence($str)
{
    return UConverter::transcode($str, 'UTF-8', 'UTF-8');
}

function replace_invalid_byte_sequence2($str)
{
    return (new UConverter('UTF-8', 'UTF-8'))->convert($str);
}

function utf8_check_encoding($str)
{
    return $str === UConverter::transcode($str, 'UTF-8', 'UTF-8');
}

function utf8_check_encoding2($str)
{
    return $str === (new UConverter('UTF-8', 'UTF-8'))->convert($str);
}

// Table 3-8. Use of U+FFFD in UTF-8 Conversion
// http://www.unicode.org/versions/Unicode6.1.0/ch03.pdf)
$str =  "\x61"."\xF1\x80\x80"."\xE1\x80"."\xC2"."\x62"."\x80"."\x63"
    ."\x80"."\xBF"."\x64";
$expected = 'a���b�c��d';

var_dump([
    $expected === replace_invalid_byte_sequence($str),
    $expected === replace_invalid_byte_sequence2($str)
],[
    false === utf8_check_encoding($str),
    false === utf8_check_encoding2($str)
]);

答案 1 :(得分:0)

我做了一些挖掘并找到了ICU unorm2_normalize() documentation。它的pErrorCode输出参数很有趣。标准ICU错误代码从utypes.h的第620行开始。所以我尝试了这个测试脚本:

$s = 'tête-à-tête';
echo "normalizer_normalize(\$s) >> " 
     . var_export(normalizer_normalize($s), 1) . "\n";
$s = "\xFF" . $s;
echo "normalizer_normalize(\$s) >> " 
     . var_export($r=normalizer_normalize($s), 1) . "\n";
if ($r===false)
    echo "normalizer_normalize() error: " 
         . intl_get_error_message() . "\n";
// which outputs:
normalizer_normalize($s) >> 'tête-à-tête'
normalizer_normalize($s) >> false
normalizer_normalize() error: Error converting input string to UTF-16: U_INVALID_CHAR_FOUND

所以我猜一个基于此的测试并寻找以下三个错误代码将是糟糕的UTF-8编码的正确指示:

  

U_INVALID_CHAR_FOUND字符转换:不可映射的输入序列。   U_TRUNCATED_CHAR_FOUND字符转换:输入序列不完整。   U_ILLEGAL_CHAR_FOUND字符转换:非法输入序列/输入单元组合。

或者当我感到懒惰时,我可以使用

normalizer_normalize($s)===false
Btw:我对ICU API规范的这一行感到困惑:

  

pErrorCode 标准ICU错误代码。   它的输入值必须通过    U_SUCCESS ()测试,否则函数   马上回来。检查    U_FAILURE ()输出或使用   功能链。 (请参阅用户指南   的信息。)

“函数立即返回”这句话鼓励我的测试重新执行,但“函数”是指unorm2_normalize()还是U_SUCCESS()?有什么想法吗?