我在用户输入上使用以下代码时遇到了一些问题:
htmlentities($string, ENT_COMPAT, 'UTF-8');
当检测到无效的多字节字符时,PHP会发出通知:
PHP警告:htmlentities():第123行/path/to/file.php中参数中的无效多字节序列
我的第一个想法是压制错误,但这是缓慢而糟糕的做法: http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html
我的第二个想法是使用ENT_IGNORE标志,但即使是PHP手册也建议不要使用它:
无声地丢弃无效的代码单元序列,而不是返回空字符串。不鼓励使用此标志,因为它是may have security implications。
进一步的原因使我得到了以下代码:
// 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);
}
不幸的是iconv 在删除/忽略无效字符时会抛出E_NOTICE:
如果将字符串// TRANSLIT附加到out_charset,则会激活音译。这意味着当一个角色无法在目标字符集中表示时,它可以通过一个或几个相似的字符来近似。如果附加字符串// IGNORE,则会无提示地丢弃无法在目标字符集中表示的字符。否则,str将从第一个非法字符中删除,并生成E_NOTICE。
所以我基本上没有选择。我宁愿使用一个久经考验的库来处理这种东西,而不是尝试使用我见过的一些基于正则表达式的解决方案。
所以这引出了我的最后一个问题: 如何在没有通知/警告/错误的情况下高效,安全地删除无效的多字节字符?
答案 0 :(得分:4)
iconv('UTF-8', "ISO-8859-1//IGNORE", $string);
对我来说非常好。似乎没有产生任何通知。
答案 1 :(得分:2)
如何在没有通知/警告/错误的情况下高效,安全地删除无效的多字节字符?
好吧,正如您已经在自己的问题中概述的那样(or at least linked),删除无效的字节序列不是一种选择。
相反,它可能会替换为替换字符U + FFFD。从PHP 5.4.0开始,您可以使用htmlentities
的ENT_SUBSTITUTE
标记。如果你不想拒绝字符串,这可能是最安全的。
iconv
将始终在最近的PHP版本中给出警告。所以它看起来不适合你。