thinkphp模板继承无效的主因是前置条件不满足:子模板首行必须绝对干净且{extend}顶格;路径须相对于view_path并带后缀;父模板需有同名{block};{include}与{extend}不可混用;tp6+已移除该语法。

ThinkPHP模板继承“写了却没效果”,绝大多数不是配置没开或语法写错,而是几个硬性前置条件被悄悄破坏了——引擎直接跳过继承逻辑,不报错、不提示,只默默渲染子模板原始内容。
子模板首行必须绝对干净
{extend} 标签必须是文件第一行的第一个字符,前面不能有任何东西:
- BOM头(尤其Windows记事本保存的UTF-8带BOM文件)
- 空格、制表符、换行符(哪怕肉眼看不见)
- PHP注释 php // 这里不行 ?> 或短标签 echo 'x'; ?>
- HTML注释 或其他任意输出
建议用编辑器开启“显示所有字符”功能,确认 {extend name="public/layout"} 真正顶格出现在第1行第1列。
路径必须严格匹配 view_path 且带后缀
name 值不是绝对路径,也不是相对当前文件的路径,而是相对于 view_path 的路径:
- 若配置中
'view_dir_name' => 'view',且view_path = app/view/,那name="public/layout"对应的就是app/view/public/layout.html - ThinkPHP 6 起强制要求写全后缀:必须是
layout.html,不能省略 .html -
name="./public/layout.html"或name="/public/layout.html"都是错误写法,不支持点号或斜杠开头
父模板至少得有一个同名 {block}
没有 {block},继承就等于没发生:
- 父模板里 必须存在
{block name="content"}...{/block}这类声明 - name 值大小写、下划线完全敏感:
"Content"≠"content"≠"CONTENT" - 即使 {block} 里面是空的,也得有这个结构,否则子模板里所有 {block} 都会被静默忽略
{include} 和 {extend} 别混着用
很多人在父模板里 {include file="common/header"},再指望子模板去覆盖 header 里的 {block}——这根本不可能生效:
- {extend} 是编译期注入:子模板内容先“塞进”父模板对应 {block},再整体编译
- {include} 是运行时引入:发生在编译完成之后,其内部 {block} 对子模板不可见
- 正确做法:把需要定制的部分(标题、JS位置等)直接放在 layout.html 的 {block} 里;公共片段(导航、页脚)用 {include} 单独引入
ThinkPHP 6+ 以上版本注意语法已移除
如果你用的是 TP6 或更高版本(尤其是 TP8),请特别注意:
- {extend}、{block}、{__BLOCK__} 等语法已被彻底移除,继续使用会报 Parse error 或页面空白
- 官方不再支持模板继承机制,推荐改用 {include} + assign() 显式传参方式
- 若仍想用类似语法,需手动安装
topthink/think-template并在 config/template.php 中明确配置'type' => 'Think' - TP8 默认使用原生 PHP 模板(.php 后缀),.html 文件需依赖 think-template 才能解析
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











