能混用,但必须清楚它们根本不在一个执行阶段——{include}是运行时引入,{extend}是编译期注入,父模板中{include}的内容对子模板的{block}不可见,路径均相对当前模板,混用易导致覆盖失效或静默失败。

能混用,但必须清楚它们根本不在一个执行阶段——混用不等于“配合”,更多是“共存”,稍不注意就会覆盖失效、路径错乱或内容丢失。
执行时机完全不同
{include} 是运行时引入,模板编译完成后才去读取并拼接文件内容;{extend} 是编译期注入,子模板内容会在编译阶段就被“塞进”父模板对应 {block} 中,再整体生成缓存文件。
- 父模板里 {include file="public/header"} 引入的 header.html,其内部写的 {block name="title"} 对子模板完全不可见
- 子模板无法覆盖 include 进来的内容里的任何 block,因为那段代码压根没参与继承编译流程
- 反过来,子模板也不能靠 {include} 去“补丁式”修改父模板已渲染好的区块
路径都是相对当前模板,不是 view 根目录
这是混用时最容易静默失败的点。比如在 view/user/index.html 里写:
- {include file="header"} → 实际找的是 view/user/header.html(不是公共头)
- {include file="public/header"} → 才会正确加载 view/public/header.html
- {extend name="public/layout"} → 对应 view/public/layout.html(不能带 .html 后缀)
路径写错,{include} 可能加载空文件,{extend} 则直接跳过不报错,页面只剩子模板内容。
真正要定制,得重构结构,别依赖混用
想让头部支持标题、JS 等可定制,正确做法不是在 header.html 里写 {block} 再指望子模板覆盖,而是:
- 把需要定制的部分(如 title、meta、script)直接放在基础布局模板(如 layout/base.html)中,用 {block name="title"}默认标题{/block} 定义
- 导航栏、页脚等纯复用内容,各自做成独立模板,用 {include file="public/header"} 在 layout 或子模板中引入
- 如果真需多层定制(比如 admin/layout 继承 base,再让 user/index 继承 admin/layout),就用纯 {extend} 链,不要掺 {include}
缓存和配置容易被忽略
混用场景下,问题常被缓存掩盖:
- 修改了 public/header.html,但页面没变?可能是模板缓存未更新,需清空 runtime/view/
- 开启了 layout_on,又写了 {extend}?TP8 中二者互斥,{extend} 会绕过 layout 流程
- 子模板第一行有空格、BOM 或注释?{extend} 将静默失效,页面不显示父模板
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











