如何在PHP中检测格式错误的UTF-8字符串?

bybem2ql  于 2023-02-15  发布在  PHP
关注(0)|答案(5)|浏览(135)

iconv函数有时会给我一个错误:

Notice:
iconv() [function.iconv]:
Detected an incomplete multibyte character in input string in [...]

在向inconv()发送数据之前,有没有办法检测UTF-8字符串中是否存在非法字符?

rks48beu

rks48beu1#

首先,注意不可能检测文本是否属于特定的不需要的编码,只能检查字符串在给定的编码中是否有效。
您可以使用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手册页上的示例。

4smxwvx5

4smxwvx52#

对于使用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);

输出(例如,对于PHP版本5.3.3 - 5.3.13,5.3.15 - 5.3.29,5.4.0 - 5.4.45)

string(4) "null"
bool(true)
1l5u6lss

1l5u6lss3#

您可以尝试使用mb_detect_encoding来检测是否有不同的字符集(与UTF-8不同),然后在需要时使用mb_convert_encoding转换为UTF-8。人们更有可能以不同的字符集为您提供有效内容,而不是提供无效的UTF-8。

czq61nw1

czq61nw14#

UTF-8中哪些字符是无效字符的规范非常清楚。您可能希望在尝试解析它之前将其去除。它们不应该存在,因此如果您能够在生成XML之前避免这些字符,那将更好。
请参阅此处以获取参考:
http://www.w3.org/TR/xml/#charsets
这并不是一个完整的列表。许多解析器也不允许一些编号较低的控制字符,但我现在找不到一个完整的列表。
不过,iconv可能对此有内置支持:
http://www.zeitoun.net/articles/clear-invalid-utf8/start

ndh0cuux

ndh0cuux5#

在iconv()前面放置一个@以抑制NOTICE,在源编码id中UTF-8后面放置一个//IGNORE以忽略无效字符:

@iconv('UTF-8//IGNORE', $destinationEncoding, $yourString);

相关问题