ThinkPHP模板中让{$name}原样输出HTML的正确方式是{|$name|raw};raw必须位于过滤器链末尾,不可与其他过滤器混用,且仅用于已安全过滤的变量。

ThinkPHP 默认会对模板变量输出做 HTML 转义,防止 XSS;如果要原样输出 HTML,必须显式取消转义,而不是靠“关闭全局转义”这种高危操作。
怎么让 {$name} 不转义直接输出 HTML
在模板中使用 {:} 语法或 {|htmlspecialchars_decode} 等过滤器是无效的,ThinkPHP 不支持这类写法。正确方式只有两种:
- 用
{|$name|raw}——raw是唯一被框架认可的“不转义”标识符 - 用
{:html_entity_decode($name)}或{:htmlspecialchars_decode($name)},但需确保变量本身是 double-escaped 的,否则可能出错 - 更稳妥的做法:在控制器里用
assign('content', $htmlString),模板里写{|$content|raw}
raw 过滤器为什么不能和其它过滤器混用
|raw 必须是管道链的最后一个处理环节,且不能跟在 |default、|nl2br 等之后。ThinkPHP 的解析逻辑是:一旦遇到 |raw,就跳过所有后续过滤和转义,直接输出原始字符串。
- ✅ 正确:
{|$desc|default='-'|raw}(default在前,raw在最后) - ❌ 错误:
{|$desc|raw|nl2br}(raw后加任何过滤都会被忽略) - ❌ 危险:
{|$user_input|raw}(未过滤的用户输入直出 = XSS 漏洞)
为什么 template.engine.default_filter 设成 '' 不起作用
在配置文件里把 default_filter 改为空字符串,看似能“关闭默认转义”,但实际上:
- 该配置只影响未显式指定过滤器的变量,如
{$name};但{|$name}仍会走默认过滤 - ThinkPHP 6.1+ 已将此配置标记为 deprecated,部分版本直接忽略
- 即使生效,也会导致所有变量都不转义,包括用户提交的昵称、评论内容等,风险极高
- 真正可控的方式,永远是按需使用
|raw,而非全局降级安全策略
最常被忽略的一点:前端 JS 里用 innerHTML 插入 |raw 输出的内容时,仍要确认后端已做过基础 XSS 过滤(比如用 htmlspecialchars() 处理过富文本白名单标签),|raw 只是“不二次转义”,不是“自动消毒”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











