tp8模板引擎强制变更:禁用{$list[0].name}等数字下标访问,须改用{volist};默认禁用{:func()}等php表达式,需配置tpl_deny_php或前置逻辑;系统函数如config()须在tpl_function白名单中声明;模板路径须全小写且跨模块引用需加@符号。

ThinkPHP8升级后模板引擎语法出现若干强制性变化,部分写法会直接导致模板编译失败或静默失效,不再兼容TP6/7旧习惯——比如{$list[0].name}直接取数组元素、{:func()}动态调用、未声明就启用PHP表达式等,这些在TP8中默认被拦截或跳过。
变量输出必须用volist遍历数组
TP8模板引擎禁止直接使用{$list[0].name}、{$list.0.name}这类点号+数字下标访问数组元素。该语法在编译阶段被直接忽略,页面空白且无报错。
必须改用{volist}标签显式遍历:
{volist name="list" item="vo"}
{$vo.name}
{/volist}原因:TP8的模板编译器对变量访问做了AST层级校验,数字下标访问触发非法节点过滤;而volist由引擎原生支持,能正确解析索引与对象属性混合结构。
PHP表达式默认被禁用
TP8模板默认关闭PHP执行能力,{:func()}、{~func()}、{php}echo 1;{/php}等全部失效,不报错也不输出,页面对应位置留空。
方法一:临时放开(仅开发环境)
修改config/template.php中'tpl_deny_php' => false
方法二:推荐做法——逻辑前置到控制器
将func()结果提前计算并assign传入,模板只做展示:$this->assign('user_name', getUserDisplayName($id))->fetch();
【tpl_deny_php设为false后,所有{php}标签和{:xxx()}均恢复执行,但生产环境务必关回true】
系统变量需白名单放行
像{:config('app.name')}、{:input('get.id')}这类系统函数调用,在TP8中默认返回空字符串,不是语法错,而是函数被拦截。
第一步:打开config/template.php
第二步:找到'tpl_function'配置项
第三步:把允许使用的函数名加进数组,例如:
'tpl_function' => ['config', 'input', 'url', 'date']
注意:未列在此数组中的函数,无论是否存在于助手函数列表,模板中调用一律返回空。
模板路径必须全小写且结构固定
TP8严格按app/{模块}/view/{控制器}/{操作}.html匹配,大小写不符即报Template not found——Windows本地可能侥幸跑通,Linux服务器必挂。
常见错误路径:
❌ app/index/View/User/index.html(View首字母大写)
❌ app/Index/view/user/index.html(模块名Index大写)
✅ 正确路径:app/index/view/user/index.html
跨模块引用必须带@符号:$this->fetch('admin@public/header')
漏掉@符号,框架会在当前模块下找,而不是admin模块。
include路径以当前模板目录为起点
{include file="header"}不是去view根目录找header.html,而是从当前模板所在目录开始找。
比如当前模板是app/index/view/user/profile.html,{include file="header"}会尝试加载app/index/view/user/header.html。
要引入公共头部,必须写相对路径或带模块前缀:
{include file="../public/header"} 或 {include file="@public/header"}
【@符号表示从view根目录开始,不是从app根目录】
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











