转义HTML特殊字符后实体不显示,页脚版权实体却正常的问题求助
哥们,你遇到的这个Why can't i submit this的问题,本质是字符串被重复转义了。咱们来一步步捋清楚:
问题根源
你看到的'其实是'(单引号的HTML实体)又被转义了一次——也就是说,用户提交的单引号'先被转成了',然后这个字符串里的&又被转成了&,叠在一起就变成了',自然没法正常显示成单引号。
而页脚的版权实体能正常显示,大概率是因为它是直接写在HTML里的,没有经过你这个自定义的escape函数或者后续的重复转义逻辑,浏览器直接解析一次就正确显示了。
排查与解决办法
1. 检查你的escape函数实现
先看看你的escape($text)是不是不小心重复调用了转义方法?比如写成了这样:
function escape($text) { // 错误:连续调用两次htmlspecialchars,导致重复转义 return htmlspecialchars(htmlspecialchars($text)); }
正确的写法应该是只转义一次,并且带上合适的参数(比如ENT_QUOTES会同时转义单双引号,适合评论场景):
function escape($text) { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); }
测试一下:把用户提交的Why can't i submit this传入这个函数,预期输出应该是Why can't i submit this,这才是正确的转义结果。
2. 检查页面渲染/模板的自动转义逻辑
如果你的escape函数本身没问题,那就要看输出评论内容的地方是不是被模板引擎或者框架自动转义了一次。比如很多模板引擎(像Twig、Blade)默认会自动转义变量,如果你已经用自定义函数转义过,就会触发二次转义。
这种情况下,要么:
- 关掉对应变量的自动转义(比如Twig里用
{{ comment|raw }},Blade里用{!! comment !!}); - 要么去掉自定义
escape函数的调用,直接依赖模板的自动转义。
3. 简单验证方法
找个测试环境,直接输出转义后的结果看看:
$userInput = "Why can't i submit this"; $escaped = escape($userInput); echo $escaped;
如果输出的是Why can't i submit this,那问题出在后续渲染环节;如果输出的就是Why can't i submit this,那肯定是escape函数内部的重复转义问题。
内容的提问来源于stack exchange,提问作者ii iml0sto1

