{block}覆盖失效是因继承未触发、父模板缺{block}或名称不匹配;{extend}须顶格首行,TP6+需带.html后缀,路径相对view_path且大小写敏感,TP6+已移除原生支持。

{block}覆盖失效不会报错,页面照常渲染,但子模板内容根本没进去。问题通常出在继承没触发、父模板没声明对应区块,或名称/写法不匹配。
检查{extend}是否真正生效
{extend name="layout"}必须严格顶格写在子模板第一行第一个字符位置。任何前置空格、空行、BOM头、PHP注释(如<?php // 注释 ?>)都会导致框架跳过继承逻辑,只渲染子模板原始内容。
- 用编辑器开启“显示所有字符”功能,确认{extend}是文件绝对首字符
- ThinkPHP 6+要求name值显式带.html后缀,例如{extend name="public/layout.html" /}
- 路径是相对于
view_path配置项的,不是相对于当前模板文件 - 路径和文件名大小写敏感,Linux下
layout.html与Layout.html是两个文件
确认父模板是否正确定义了{block}
父模板中必须存在同名且拼写完全一致的{block name="xxx"}{/block},子模板才能覆盖。漏写、大小写错误(如content ≠ Content)、下划线缺失,都会导致子内容被静默丢弃。
- 检查父模板是否存在
{block name="title"}默认标题{/block}这类结构 - name值严格区分大小写、下划线,不会自动转换或忽略差异
- ThinkPHP 6起已移除原生模板引擎对{extend}/{block}的支持,若未安装
topthink/think-view扩展,语法直接不识别
理解{block}是替换而非追加
{block}本质是“完全替换”,不是在父内容后追加。子模板写了{block name="js"}<script>init();</script>{/block},父模板中该区块原有JS代码就彻底消失。
立即学习“PHP免费学习笔记(深入)”;
- 想保留父内容再叠加,父模板需写作:
{block name="js"}{__BLOCK__}<script>loadMore();</script>{/block} - 同一子模板内重复定义同名{block},只有最后一个生效
- {include}引入的文件内部的{block}对当前子模板不可见,无法被覆盖
清除缓存与编译残留
改完模板仍不生效,大概率是缓存干扰。ThinkPHP模板缓存分两层:Runtime/Cache下的编译PHP文件,以及Runtime/Temp里的哈希映射表。只删Cache目录,旧映射仍在,框架会继续执行损坏的缓存版本。
- 开发阶段建议关闭模板缓存:
'cache' => false(config/view.php) - 手动清空
runtime/view/和runtime/temp/整个目录 - 刷新页面后查看最终HTML源码:如果开头就是子模板内容(没有布局中的<html>或公共header),说明{extend}根本没执行



















