iconv函数有时会给我一个错误:
Notice:
iconv() [function.iconv]:
Detected an incomplete multibyte character in input string in [...]
是否有一种方法可以检测在将数据发送到inconv()之前UTF-8字符串中是否存在非法字符?
首先,注意不可能检测文本是否属于特定的不希望的编码。您只能检查字符串在给定的编码中是否有效。
您可以使用自PHP 4.3.5以来preg_match
[PHP Manual]中提供的UTF-8有效性检查。如果给定无效字符串,它将返回0
(不含任何附加信息):
$isUTF8 = preg_match('//u', $string);
另一种可能是mb_check_encoding
[PHP Manual]:
$validUTF8 = mb_check_encoding($string, 'UTF-8');
另一个可以使用的函数是mb_detect_encoding
[PHP Manual]:
$validUTF8 = ! (false === mb_detect_encoding($string, 'UTF-8', true));
将strict
参数设置为true
是很重要的。
另外,iconv
[PHP Manual]允许您动态更改/删除无效序列。(但是,如果iconv
遇到这样的序列,它会生成一个通知;)
echo 'TRANSLIT : ', iconv("UTF-8", "ISO-8859-1//TRANSLIT", $string), PHP_EOL;
echo 'IGNORE : ', iconv("UTF-8", "ISO-8859-1//IGNORE", $string), PHP_EOL;
您可以使用@
检查返回字符串的长度:
strlen($string) === strlen(@iconv('UTF-8', 'UTF-8//IGNORE', $string));
查看iconv
手册页上的示例
使用json_encode,试试json_last_error
<?php
// An invalid UTF8 sequence
$text = "'xB1'x31";
$json = json_encode($text);
$error = json_last_error();
var_dump($json, $error === JSON_ERROR_UTF8);
5.3.3 输出(例如PHP版本——5.3.13 5.3.15——5.3.29 5.4.0 - 5.4.45)
string(4) "null"
bool(true)
您可以尝试使用mb_detect_encoding
来检测您是否有不同的字符集(而不是UTF-8),然后mb_convert_encoding
在需要时转换为UTF-8。更有可能的是,人们给你的是不同字符集的有效内容,而不是无效的UTF-8。
对于哪些字符在UTF-8中无效的规范是非常清楚的。在尝试解析它之前,您可能希望去掉这些内容。它们不应该在那里,所以如果你能在生成XML之前就避免它,那就更好了。
参考:
http://www.w3.org/TR/xml/数据集
这不是一个完整的列表。许多解析器也不允许一些低编号的控制字符,但我现在找不到一个全面的列表。
但是,iconv可能有内置的支持:
http://www.zeitoun.net/articles/clear-invalid-utf8/start在iconv()前加一个@
来抑制NOTICE,在源编码id的UTF-8后加一个//IGNORE来忽略无效字符:
@iconv('UTF-8//IGNORE', $destinationEncoding, $yourString);