应使用default修饰符兜底未定义变量,如{$user.name|default='匿名用户'};调试时用{:dump($this->gettemplatevars())}定位缺失变量;避免用isset判断,改用empty过滤器或default后判断。

ThinkPHP模板中变量输出为空,通常不是模板写错了,而是变量根本没传进来、传错类型,或被模板引擎“拦”在了外面。关键得看是整块内容空,还是个别字段空,处理方式完全不同。
变量压根没 assign 进来
控制器里漏写了 $this->assign('user', $user),模板却直接写 {$user.name},PHP 就会报 Notice 并中断渲染,结果页面空白或字段消失。
- 调试时在模板开头加
{:dump($this->getTemplateVars())},能立刻看到哪些变量实际传进来了 - 别依赖
isset($user)判断——它在模板里不安全,未定义变量会先触发错误 - 统一用
{$user.name|default='-'},default能兜住 null、空字符串、未定义三种情况
变量传了但类型不对
比如数据库查询用了 select() 或 toArray(),把原本的 Query 对象或 Paginator 实例转成了纯数组,再传给模板后,{$list->render()} 就会失效,{$list.total()} 也会报错。
-
User::where(...)->paginate(10)✅ —— 返回 Paginator 对象,支持 render() -
User::where(...)->select()->paginate(10)❌ —— select() 提前执行,paginate 只是对数组假分页 -
$list = User::paginate(10)->toArray()❌ —— 对象元信息彻底丢失,只剩数据
模板缓存或解析异常导致显示为空
改完模板但页面还是空,大概率是 runtime/view/ 下的缓存没更新,或者标签语法和当前 TP 版本不兼容。
- 删掉
runtime/view/全部内容(不是只删某一个文件) - 开发时设
'cache' => false关闭模板缓存 - TP5.1+ 中
{volist}只认key和id属性,写成index="i"会静默跳过整块 - 嵌套超过 3 层需检查
template.taglib_level配置,默认为 3
HTML 被自动转义,看起来像“空”
特别是分页 {$list->render()} 输出了一堆 HTML 标签源码(如 <div class="pagination">...),而不是可点击的页码,其实是被 <code>htmlspecialchars 转义了。
- TP6 必须写成
{$list->render|raw} - TP5.1 若用
widget方式,应写{:widget('think\paginator\driver\Bootstrap', $list)} - TP3 用
|htmlspecialchars_decode或确保开启了DEFAULT_FILTER











