ThinkPHP的{include}标签只认view目录下的相对路径,正确写法有三种:子目录相对路径、绝对路径(推荐)和跨模块引用;传参须用字符串键值对,静态资源需用{__STATIC__}常量,布局模板更利于统一结构。

路径必须从 view 目录开始算,不能用 ../ 或 ./
ThinkPHP 的 {include} 标签不走 PHP 的 include_path,也不识别传统相对路径。它只认「模板目录(即 view/)下的相对路径」,且默认以当前模板所在子目录为起点查找——这导致 90% 的报错源于路径写错。
正确写法只有三种:
-
{include file="common/header" /}→ 找view/common/header.html -
{include file="/common/header" /}→ 绝对路径写法,明确从view/根开始(推荐,不易歧义) -
{include file="admin@common/header" /}→ 跨模块引用,找view/admin/common/header.html(前提是admin是已注册模块)
错误示范:{include file="../common/header" /}、{include file="./header" /}、{include file="header.html" /} —— 全部会触发 404 或空白渲染。
传参要用字符串键值对,别写 PHP 数组
被包含模板(如 header.html)能直接访问父模板变量,但显式传参更安全、可读性更强。注意语法限制:ThinkPHP 不解析 PHP 原生数组或对象字面量。
立即学习“PHP免费学习笔记(深入)”;
- 传单个变量:
{include file="/common/header" title="首页" is_login=1 /}→ 在header.html中用{$title}、{$is_login} - 传动态变量:
{include file="/common/header" user_name=$user.name avatar_url=$user.avatar /} - 禁止写法:
{include file="/common/header" data="[title=>'首页']" /}→ 模板引擎直接忽略该参数
若需传复杂结构(如菜单数组),应在控制器中先 $this->assign('menu_list', $menus),再在模板里 {include file="/common/header" menu_list=$menu_list /}。
静态资源路径乱了?不是 include 的锅,是 HTML 解析问题
{include} 只负责把 HTML 片段拼进去,不改写里面的 <link>、<script> 或 <img> 路径。这些路径仍按当前页面 URL 解析,所以公共头部里的 css/base.css 在 /admin/user/edit 页面会尝试加载 /admin/user/css/base.css。
解决办法只有一个:所有静态资源必须用 {__STATIC__} 助手常量:
- 错:
<link rel="stylesheet" href="css/base.css"> - 对:
<link rel="stylesheet" href="{__STATIC__}/css/base.css">
{__STATIC__} 会被自动替换为配置的 static 目录 URL(如 /static),确保路径始终正确。
布局模板 layout.html 更适合全站统一结构
如果 header + content + footer 是固定三段式,优先用布局模板而非到处写 {include}。它更清晰、更易维护,且天然规避嵌套路径混乱问题。
启用方式:在 config/template.php 加:
'template' => [
'layout_on' => true,
'layout_name' => 'layout',
]
然后建 view/layout.html,内容类似:
{include file="/common/header" /}
{__CONTENT__}
{include file="/common/footer" /}
此时任意模板(如 view/index/index.html)只需专注写业务内容,无需手动引入头尾。注意:{__CONTENT__} 是唯一占位符,不能写成 {CONTENT} 或其它变体。
容易被忽略的一点:修改 layout.html 后,必须清空 runtime/view/ 缓存,否则旧布局仍生效——这不是 bug,是模板编译机制决定的。



















