{extend}必须严格位于子模板第一行,前面不得有任何字符;name值需匹配view_path下的路径且TP6起须带.html后缀;父模板须有同名{block},否则子模板内容被静默忽略。

ThinkPHP里{extend}必须写在子模板第一行
否则整个继承链就断了,页面会直接渲染子模板原始内容,不走父模板任何结构。这不是警告,是硬性语法限制。
-
{extend}前面不能有空格、空行、<?php ?>注释或任何输出 -
name值不带后缀,比如public/base对应app/view/public/base.html - 路径是相对于
view_path的,别按文件系统层级瞎猜——TP6起强制要求写.html后缀 - 如果写了
{extends}(多了一个s)或{extend name="Base"}(大小写错),不会报错,但静默失效
父模板里{block}名称拼写必须和子模板完全一致
大小写、下划线、空格,差一个字符,子模板里的{block name="content"}就匹配不上父模板的{block name="Content"},结果是内容直接丢弃,页面空白或局部缺失,且无任何提示。
- 父模板中没定义同名
{block},子模板对应区块内容会被忽略(不是报错,是消失) - 想保留父模板内容再追加,得用
{__BLOCK__},不是{{ super() }}(那是Jinja2/Twig的) - 多个
{block}之间不能嵌套,也不能跨行写在PHP标签里——{block}是模板引擎解析阶段处理的,PHP代码块内无效
layout_on配置对return $this->fetch()基本无效
开了'layout_on'=>true,不代表控制器里return $this->fetch();就会自动套layout.html。它只影响View::fetch()等底层调用,和{extend}是两套独立机制。
- 想用
layout机制,得在控制器里显式调用$this->layout('layout'),再fetch() - 如果同时用了
{extend}又开了layout_on,大概率后者被忽略,甚至触发冲突报错 -
layout.html里只能放{__CONTENT__},不支持{block};反过来,{extend}模板里不能出现{__CONTENT__}
include进来的文件不参与继承链
这是最常被误用的一点:在父模板里{include file="public/header" /},然后指望子模板能覆盖header.html里的某个{block}——不可能。include是运行时引入,发生在编译之后,子模板根本看不到它内部结构。
立即学习“PHP免费学习笔记(深入)”;
- 公共头尾、导航栏这类需要复用又可能局部定制的内容,应该抽成带
{block}的独立布局模板,再让base模板继承它 - 不要试图用
{include}去“组装”可继承结构,该用{extend}的地方必须用{extend} - include适合静态片段(如一段JS初始化代码),但凡涉及动态替换、条件渲染、SEO字段注入,就得回到
{block}体系
{extend}和layout看起来都在做“套壳”,但它们的执行时机、作用域、语法约束完全不同。混用时问题不会立刻暴露,而是等到某次改版后,某个页面突然样式错乱或区块消失,才意识到是继承链在某个环节悄悄断掉了。



















