PHP:过滤输入后的编码问题排查与解决求助
解决UTF-8字符被
FILTER_SANITIZE_STRING错误编码的问题 嘿,这个问题我之前踩过坑!本质是FILTER_SANITIZE_STRING搭配FILTER_FLAG_ENCODE_HIGH时,对多字节UTF-8字符的处理逻辑有问题——它会把UTF-8字符拆成单个字节,再把每个字节单独编码成HTML实体。比如你输入的ù,它的UTF-8编码是0xC3 0xB9(对应十进制195和185),就被拆成了ù,再加上转义就变成了ù。
下面是两步恢复原始字符的可行方案:
步骤1:还原转义后的实体
首先得把被转义的实体字符串还原成原始的实体格式,用htmlspecialchars_decode()处理:
$encoded_str = "ù"; // 你拿到的转义后字符串 $raw_entities = htmlspecialchars_decode($encoded_str); // 现在$raw_entities的值是"ù"
步骤2:把实体组合成UTF-8字符
接下来,我们需要把这两个单独的字节实体转成对应的字节,再组合成原始的UTF-8字符。用html_entity_decode()时指定编码为ISO-8859-1(因为每个实体对应的是单个Latin-1字节值),就能得到正确的UTF-8字符:
$original_char = html_entity_decode($raw_entities, ENT_COMPAT, 'ISO-8859-1'); echo $original_char; // 输出:ù
额外建议:避免后续再踩这个坑
另外要提醒你,FILTER_SANITIZE_STRING在PHP 8.1版本已经被废弃了,而且它对多字节字符的处理本来就不太友好。如果你的需求是清理输入并存入UTF-8编码的数据库,更推荐:
- 确保数据库连接是UTF-8编码(比如PDO连接时指定
charset=utf8mb4,比utf8支持更多特殊字符) - 用参数绑定(PDO或mysqli的预处理语句)来防止SQL注入,不需要手动转义实体
- 如果是要输出到HTML页面,再用
htmlspecialchars()处理,这样能正确识别并处理UTF-8字符
至于为什么utf8_decode()没用?因为它的作用是把UTF-8字符串转成ISO-8859-1,但你的输入是HTML实体字符串,不是原始的UTF-8字符,所以直接用它当然起不到作用啦。
内容的提问来源于stack exchange,提问作者the_real_doc
相关产品推荐
相关产品推荐

