删除无效/不完整的多字节字符

Dea*_*ean 8 php utf-8 iconv

我在用户输入上使用以下代码时遇到一些问题:

htmlentities($string, ENT_COMPAT, 'UTF-8');
Run Code Online (Sandbox Code Playgroud)

当检测到无效的多字节字符时,PHP会发出通知:

PHP警告:htmlentities():第123行的/path/to/file.php中的参数中的无效多字节序列

我的第一个想法是压制错误,但这是缓慢而糟糕的做法:http: //derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html

我的第二个想法是使用ENT_IGNORE标志,但即使是PHP手册也建议不要使用它:

无声地丢弃无效的代码单元序列,而不是返回空字符串.不鼓励使用此标志,因为它可能具有安全隐患.

还有一点原因让我得到了以下代码:

    // detect encoding
$encoding =  mb_detect_encoding($query);
if($encoding != 'UTF-8') {
    $query = mb_convert_encoding($query, 'UTF-8', $encoding);
} else {
    // strip out invalid utf8 sequences
    $query = iconv('UTF-8', 'UTF-8//IGNORE', $query);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,iconv 在删除/忽略无效字符时也会抛出E_NOTICE:

如果将字符串// TRANSLIT附加到out_charset,则会激活音译.这意味着当一个角色无法在目标字符集中表示时,它可以通过一个或几个相似的字符来近似.如果附加字符串// IGNORE,则会无提示地丢弃无法在目标字符集中表示的字符.否则,从第一个非法字符中删除str,并生成E_NOTICE.

所以我基本上没有选择.我宁愿使用一个久经考验的库来处理这种东西,而不是尝试使用我见过的一些基于正则表达式的解决方案.

因此,这引出了我的最后一个问题: 如何在没有通知/警告/错误的情况下有效,安全地删除无效的多字节字符?

hak*_*kre 3

如何有效、安全地删除无效的多字节字符,而不会出现通知/警告/错误?

好吧,正如您自己(或至少链接)的问题中已经概述的那样,删除无效的字节序列不是一个选项。

相反,它应该被替换为替换字符 U+FFFD。从 PHP 5.4.0 开始,您可以使用 的ENT_SUBSTITUTE标志htmlentities。如果您不想拒绝该字符串,这可能是最安全的。

iconv在最近的 PHP 版本中,如果不删除整个字符串,总会给你警告。所以它看起来对你来说不是一个好的选择。