thinkphp 5 的 {include} 标签不支持 php 原生相对路径(如 ./header.html),只认模板逻辑路径,起点为当前模板目录;正确用法仅三种:{include file="public/header"}、{include file="admin@public/header"} 或推荐的绝对路径 {include file="/public/header"}。

ThinkPHP 5 的 {include} 标签不认 PHP 原生相对路径
直接写 ./header.html 或 ../public/header.html 必然报错,因为 ThinkPHP 的模板引擎压根不走 PHP 的 include_path,也不解析 ./、../ 这类 Unix 风格的相对路径。它只认「模板目录下的逻辑路径」,且默认起点是当前模板所在目录(不是 PHP 执行入口,也不是浏览器请求路径)。
常见错误现象:
- 页面空白或提示
Template not found - 控制台无报错但内容没渲染出来(其实是 include 失败后静默跳过)
- 路径在本地开发环境能跑,部署到 Nginx/Apache 后 404(因路径解析逻辑与 Web 服务器无关)
正确做法只有三种:
-
{include file="public/header"}→ 从当前模板同级目录开始找,最终定位到view/当前模块名/public/header.html -
{include file="admin@public/header"}→ 跨模块引用,找view/admin/public/header.html(前提是admin是已注册模块) -
{include file="/public/header"}→ 绝对路径写法,强制从view/根目录开始,对应view/public/header.html,推荐优先用这个
静态资源(CSS/JS/图片)必须用 {__STATIC__} 替换前缀
HTML 中写的 <link href="static/css/app.css"> 在 ThinkPHP 模板里会失效——因为浏览器请求的是相对于当前 URL 的路径,而模板编译后输出的 HTML 并不自动补全 base URL。
正确写法是配合配置项 __STATIC__:
- 先确认 config/template.php 中已定义:
'tpl_replace_string' => ['__STATIC__' => '/static'] - 模板中写:
<link rel="stylesheet" href="%7B__STATIC__%7D/css/app.css"> - 生成的 HTML 就是:
<link rel="stylesheet" href="/static/css/app.css">,浏览器能正确定位
别手滑写成 {__STATIC__}/../static/css/app.css 或硬编码 /public/static/...,前者多了一层 ../ 容易断链,后者绕过了配置,不利于环境切换。
跨模块引入模板时,“模块名@路径”中的模块名必须真实存在
{include file="home@public/footer"} 看起来很直观,但如果项目里根本没有 home 模块(比如你实际模块叫 index 或 portal),ThinkPHP 就会在 view/home/ 下找,必然 404。
验证方式很简单:
- 进
application/目录,看子文件夹名是否和@前面写的完全一致(区分大小写) - 检查
route.php或模块配置,确认该模块已启用 - 不确定时,改用绝对路径
{include file="/public/footer"}更稳妥
注意:@ 语法仅用于 {include},不适用于 href、src 等 HTML 属性。
调试路径问题最有效的办法:看浏览器源码 + 手动拼 URL
别猜、别试、别改一堆再刷新——直接右键「查看网页源代码」,复制出 {include} 编译后的实际 URL(比如 /index.php?s=/public/header),粘贴到新标签页打开。
如果返回 404,说明路径没映射到真实文件;如果返回模板内容,说明路径对了但可能有语法错误。
关键点:
- ThinkPHP 的模板包含不是文件系统级 include,而是通过路由解析 + 模板编译实现的,所以
file_exists()检查无意义 - 路径错误时不会抛异常,只会静默忽略,这是最容易被忽略的坑
- 所有路径都以
view/为根,和public/、application/无关
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











