thinkphp的{include}标签仅支持以view_path为根的相对路径,不支持系统绝对路径或../、./等路径遍历写法,因其存在安全风险、缓存失效及跨环境不一致问题;动态需求应通过变量控制子目录或使用原生html引入。

ThinkPHP的{include}根本不是PHP的include函数
它只是模板引擎(ThinkTemplate)解析时的一个标签,底层不走include或require,而是读取文件内容后拼进当前模板。所以你写{include file="/var/www/html/app/view/public/header.html"}会直接报错或渲染空白——引擎只认「模板目录下的相对路径」,压根不解析系统绝对路径。
{include file="..."}的路径规则到底是什么
所有路径都以view_path配置值为根目录,且必须是该目录下的**相对路径**:
-
{include file="public/header"}→ 对应view_path . 'public/header.html'(推荐,语义清晰) -
{include file="/public/header"}→ 也是从view_path根开始,等价于上一条(“/”在这里是模板路径的根标记,不是系统根) -
{include file="admin@public/header"}→ 走模块视图目录,即view_path . '../admin/view/public/header.html'(需模块存在且配置有效) - 写
{include file="./header"}或{include file="../common/header"}→ 引擎尝试在当前模板同级目录找,几乎必失败,且无任何错误提示,只渲染空白
为什么禁止../和./?不只是设计选择
这是安全与可维护双重约束:
- 路径遍历风险:若模板引擎支持
../,攻击者可能通过可控模板变量(如{include file="$user_input"})突破view_path边界,读取config/database.php等敏感文件 - 缓存失效难定位:ThinkPHP模板编译后生成PHP文件,含硬编码路径;用
../会导致不同模板里同一{include}指向不同物理文件,缓存命中率暴跌,修改后常需手动清空runtime/view/ - 跨环境不一致:Windows不区分大小写,Linux严格区分;相对路径易因开发/部署目录层级不同而断裂,而
view_path下统一管理的路径结构稳定
想用绝对路径?换思路,别硬塞
真有动态路径需求(比如多主题切换),不要试图把系统绝对路径喂给{include},而是:
- 把不同主题模板统一放在
view/子目录下,例如view/theme-dark/common/header.html,再用变量控制:{include file="$theme_name@common/header"} - 在控制器中用
View::assign()传入预处理好的HTML字符串,绕过{include}机制本身 - 若必须加载非模板目录文件(如
public/static/js/config.js),改用原生<script src="%7B__STATIC__%7D/js/config.js"></script>,别动{include}
最易被忽略的一点:改完路径后,runtime/view/里的编译缓存不会自动更新,模板仍按旧路径找——删掉这个目录再试,否则永远在调试一个已修复的假问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











