thinkphp模板继承失效主因是{extend}未置于子模板首行、路径错误或父模板缺少{block}。需确保无bom/空格、name值匹配view_path、父模板含{block}、大小写严格一致,且不可混用{extend}与{\_\_content\_\_}。

ThinkPHP模板继承不是“开了就能用”,核心失效原因90%出在路径、语法顺序或混淆了layout机制。
为什么{extend}写了但父模板内容完全不显示
最常见的是{extend}没放在子模板第一行——前面有空格、空行、BOM头、PHP注释或<?php echo 'xxx'; ?>都会导致解析失败,引擎直接跳过继承逻辑,只渲染子模板原始内容。
- 检查子模板文件开头:用编辑器显示所有字符,确认
{extend name="public/base"}是真正第一行,前面无任何字符 - 确认
name值是相对于view_path的路径,比如view_path = app/view/,那public/base对应的就是app/view/public/base.html(TP6起必须带.html后缀) - 父模板
base.html里至少得有一个{block name="xxx"},否则子模板的{block}会被静默忽略(不报错,但内容消失)
子模板改了{block}但页面还是显示父模板默认内容
这不是缓存问题,而是覆盖规则被误读:{block}只做“替换”,不是“追加”。如果父模板{block name="title"}里写了首页,子模板写{block name="title"}后台管理{/block},结果就是“后台管理”——父内容被整个换掉。
- 想保留父内容再加点东西?父模板得写成
{block name="title"}{__BLOCK__} - 后台系统{/block},其中{__BLOCK__}是占位符,表示插入子模板该block的内容 - 大小写和下划线必须完全一致:
name="Header"≠name="header",TP不会自动转换 - 不能在子模板里重复定义同名
block,后出现的那个生效,前面的被丢弃
{include}和{extend}能不能混着用
能混,但必须清楚它们的执行时机完全不同:{include}是运行时引入,{extend}是编译期注入。这意味着父模板里{include file="public/header"}里的任何{block},子模板都覆盖不了。
- 错误做法:在
header.html里写{block name="logo"}xxx{/block},指望子模板去改——无效 - 正确做法:把需要定制的部分(如标题、JS加载)直接抽到
base.html的{block}里;公共片段(导航、页脚)各自{include},不依赖继承链 - 如果真要动态控制
header内容,就让header.html本身也支持{block},再让base.html继承它,形成多层继承链
layout_on开启后{extend}还是不生效
'layout_on' => true只影响layout机制(即{__CONTENT__}包裹),跟{extend}完全无关。很多人在这里卡住,是因为误以为开这个配置才能用继承。
-
{extend}不需要任何配置项,只要语法对、路径对、结构对,它就工作 -
layout_on开启后,控制器调用$this->layout('layout')才会生效;而return $this->fetch()默认不走layout,除非你显式调用 - 二者绝对不能混在同一模板中:一个文件里既有
{extend}又有{__CONTENT__},结果不可预测,大概率报错或静默失效
真正容易被忽略的点是:TP6强制要求模板后缀(.html),且{extend}路径不支持别名或通配符;父模板里{block}一旦拼错名字或漏写闭合标签,子模板对应内容就彻底消失,连警告都没有。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











