ThinkPHP模板布局与继承是两种独立机制:布局靠layout_on配置或{layout}标签实现全站统一外壳,仅一个__CONTENT__插入点;继承需显式{extend name="base"}首行声明+{block}区块覆盖,支持多级命名区块完全替换或__BLOCK__追加,二者不可混用。

ThinkPHP 的模板布局和模板继承是两个不同机制,但常被混用。布局(layout)靠配置或 {layout} 标签触发,适合全站统一外壳;模板继承({extend} + {block})更灵活,支持多级区块覆盖,需手动声明且不依赖全局开关。
布局(Layout):全局统一外壳
适合头部、尾部、侧栏等固定结构,子模板内容填入指定占位符。
- 开启方式:在配置文件中设置
'template'=>['layout_on'=>true, 'layout_name'=>'layout/layout'],对应view/layout/layout.html - 布局文件里用
{__CONTENT__}表示子模板插入点,例如:{include file="public/header"}{__CONTENT__}{include file="public/footer"} - 局部关闭:在某个子模板第一行写
{__NOLAYOUT__} - 动态切换:控制器中调用
$this->view->engine->layout('Layout/admin')
模板继承:基于 extend + block 的区块覆盖
不是自动生效,必须显式声明,且对格式极其敏感。
- 子模板第一行必须是
{extend name="base"}(无缩进、无空行、无 BOM、不带后缀、不能写在 PHP 注释后) - 基础模板(如
view/base.html)中定义{block name="title"}默认标题{/block} - 子模板中同名
{block name="title"}{$title}{/block}会**完全替换**基础模板中该区块全部内容 - 想保留父内容再追加?用
{__BLOCK__}:{block name="script"}{__BLOCK__}<script>more();</script>{/block}
常见失效原因与排查
页面直接显示 {block name="xxx"} 原文,说明继承根本没触发。
- 检查子模板首行是否为
{extend name="xxx"},拼错成{extends}或换行就失效 - 查看浏览器源码:开头就是子模板内容(没有布局的
),说明extend未执行 - 确认基础模板真实存在,路径大小写一致(Linux 下
Base.html ≠ base.html) - 清空模板缓存,避免旧缓存掩盖变更
布局 vs 继承:怎么选?
布局适合“套壳”,比如所有页面共用 header + footer + __CONTENT__;继承适合“模块化定制”,比如 admin/base 定义菜单、权限栏、操作区等多区块,各子页按需重写其中一两个。
- 布局不支持区块级控制,只提供单个内容插入点
- 继承支持任意数量命名区块,但要求每个
{block}都有对应定义,否则内容丢失且无提示 - 二者不可混用:开了
layout_on后再写{extend},可能冲突;建议二选一,推荐继承——更可控、更清晰
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











