tp6取消模板变量默认html转义,易引发xss,须显式用{|html}或设default_filter;移除{:function()}语法;|default在tp6中对空字符串不生效,建议用{?:}或{|empty};安全过滤应统一用{|html}而非{|htmlspecialchars}。

ThinkPHP 5.0/5.1 中 {\$var} 默认自动转义,6.x 取消了
TP5 系统默认对模板变量输出做 HTML 实体转义(htmlspecialchars),比如 {\$content} 输出 <script></script> 会变成纯文本;而 TP6 默认关闭该行为,直接原样输出——这是最常导致 XSS 漏洞被意外引入的地方。
实操建议:
- TP5 升级到 TP6 后,所有含用户输入的模板变量(如
{\$user_input})必须显式加|html过滤:{\$user_input|html} - 若想全局恢复 TP5 行为,可在配置
template.php中设置'default_filter' => 'html',但注意这会影响所有变量,包括已手动过滤过的 - TP6 的
|raw是绕过过滤的唯一方式,用它前务必确认内容可信(比如后台富文本编辑器生成的 HTML)
TP6 的 think\template\driver\Think 不再支持 {:function()} 写法
TP5 允许在模板中直接写 {:date('Y-m-d')} 或 {:config('app_debug')},TP6 移除了该语法支持,运行时抛出 ParseError: syntax error 或空白输出。
实操建议:
- 把逻辑全部移到控制器或模板赋值中,例如改用
$this->assign('now_date', date('Y-m-d')),再在模板中写{\$now_date} - 需要复用函数?封装成模板引擎的
extend函数,在config/template.php的'taglib_pre_load'或自定义标签库中注册 - 别试图用
{\$Think.config.app_debug}代替——TP6 已移除Think变量,该写法直接不解析
TP5 的 {\$var|default='xxx'} 在 TP6 中行为不一致
TP5 对空字符串、null、false 都触发 default;TP6 仅对 null 和未定义变量生效,空字符串 '' 和 0 会被原样输出,容易造成前端显示异常(比如头像 URL 为空却没 fallback)。
实操建议:
- 判断空值应改用
{\$var ?: 'xxx'}(三元运算符),它对''、0、false、null均有效 - 若坚持用
|default,需配合|empty:{\$var|empty='xxx'}——但注意|empty是 TP6 新增过滤器,TP5 不支持 - 升级前全项目 grep
|default=,逐个验证变量可能取值,尤其注意数据库字段允许为空字符串的场景
安全过滤链里 |htmlspecialchars 和 |html 不是等价的
TP5/6 都提供 |html,但它只是调用 htmlspecialchars(\$str, ENT_QUOTES, 'UTF-8');而手写 |htmlspecialchars 时若漏传参数(如没指定编码),在 GBK 环境下可能被绕过(二次解码 XSS)。
实操建议:
- 一律用内置
|html,不要自己写|htmlspecialchars——它已固化参数,更安全 - 自定义过滤器若需调用
htmlspecialchars,必须显式传参:htmlspecialchars(\$str, ENT_QUOTES, 'UTF-8') -
|html不处理换行符,如需保留\n显示为<br>,得组合使用:{\$text|html|nl2br}
真正麻烦的是混合渲染场景:比如 Vue 组件里嵌套 ThinkPHP 模板变量,或者前后端共用一套模板。这时候过滤时机和层级极易错乱——不是加一个 |html 就能解决的,得从数据流源头控制信任边界。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











