ThinkPHP 5.0 中的 __ROOT__ 等模板常量是通过 tpl_replace_string 在编译前纯文本替换实现的,需在 template 配置块内明确定义;自定义常量如 SITE_NAME 则须用 define() 定义并以 {:SITE_NAME} 方式输出,二者机制不同、互不兼容。

ThinkPHP 5.0 中的模板常量(如 __ROOT__、__STATIC__ 等)不是框架自动注入的变量,而是通过配置项 tpl_replace_string 在模板编译前做纯文本替换实现的。必须在 config.php 的 template 配置块内明确定义,否则模板中写 __ROOT__ 就只是原样输出,不会被替换成真实路径。
在 config.php 的 template 配置中添加 tpl_replace_string
打开应用配置文件 application/config.php,找到 'template' => [ ... ] 数组,在其中加入 'tpl_replace_string' 项:
- 确保它位于
'template'数组内部,不能写在根配置层或'view'分组里 - 值必须是关联数组,键为模板中要写的占位符(如
'__ROOT__'),值为要替换的字符串(如ROOT_PATH) -
ROOT_PATH是 ThinkPHP 启动时定义的 PHP 常量,直接写常量名,不要加引号
示例配置片段:
'template' => [
'type' => 'Think',
'view_path' => '',
'view_suffix' => 'html',
// ... 其他默认配置保持不变
'tpl_replace_string' => [
'__ROOT__' => ROOT_PATH,
'__STATIC__' => ROOT_PATH . 'static/',
'__CSS__' => ROOT_PATH . 'static/css/',
'__JS__' => ROOT_PATH . 'static/js/',
],
],
自定义常量必须用 define() + 模板 {:常量名} 方式
如果想在模板中用 {:SITE_NAME} 这类语法输出自定义常量,和 __ROOT__ 完全不同机制:
- 需在
app/common.php中用define('SITE_NAME', 'MySite');显式定义 - 确保
common.php已被自动加载(检查composer.json的autoload.files是否包含它) - 模板中写
{:SITE_NAME},不能写{$Think.const.SITE_NAME}或带括号形式 - 修改后需清缓存:
php think clear或手动删掉runtime/template/目录
常见不生效原因及处理
配置写了却没效果?优先排查这三项:
- 模板缓存未清除:ThinkPHP 默认开启
tpl_cache,旧编译文件仍存在runtime/template/下,直接删除该目录最可靠 - 配置位置错误:
tpl_replace_string必须嵌套在'template' => [ ]内,写在外面或写成'view' => [ 'tpl_replace_string' => [...] ]都无效 - 路径末尾重复斜杠:比如
ROOT_PATH结尾已有/,又在模板中写__ROOT__/css/app.css,会导致//css/app.css,建议统一用rtrim(ROOT_PATH, '/')处理
不能在 tpl_replace_string 里写动态表达式
tpl_replace_string 是编译期静态替换,不执行 PHP 代码:
- 不支持函数调用,例如
'__ROOT__' => dirname(__DIR__) . '/public'会报错或失效 - 不支持拼接变量,例如
'__THEME__' => '__ROOT__/theme/{$theme}'中的{$theme}不会被解析,只会原样保留 - 不感知作用域,不能引用控制器传入的变量或 $Think.config.xxx
如需动态路径,应由控制器 assign 给模板变量,再在模板中用 {$theme_path} 输出。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











