thinkphp配置加载顺序为:convention.php→config/app.php→config/{env}.php→模块config.php→runtime/config.php;后加载覆盖先加载,.env需显式调用env()才生效,runtime/config.php是唯一可持久写入位置。

ThinkPHP 的配置覆盖不是“谁写得晚谁生效”,而是有严格加载顺序和层级关系的系统行为。改了 config/database.php 却不生效?大概率是 .env 或 runtime/config.php 在你没注意时悄悄覆盖了它。
配置加载顺序决定谁覆盖谁
ThinkPHP 启动时按固定链条加载配置,后加载的会覆盖同名键:
thinkphp/convention.php → config/app.php → config/{env}.php(如 config/dev.php)→ 模块级 config.php → runtime/config.php
关键点:
-
convention.php是框架默认值,不建议直接改,应通过后续文件覆盖 -
{env}.php仅在APP_ENV=dev且APP_DEBUG=true时才加载,否则跳过 -
runtime/config.php是唯一能被Config::set()持久写入的位置,其他文件修改需重启服务 - 模块配置(如
app/admin/config/database.php)只在对应模块被访问时加载,但一旦加载就覆盖应用级配置
.env 文件的覆盖能力有限制
.env 看似优先级最高,但它只做「一级键映射」,且依赖 PHP 配置文件里显式调用 env() 才能生效。
常见失效场景:
-
.env里写DB_HOST=192.168.1.100,但config/database.php中是'hostname' => env('DATABASE_HOSTNAME', '127.0.0.1')—— 键名不匹配,根本不会读取 -
.env文件编码含 BOM 头,或放在子目录下(必须在项目根目录) - 没清缓存:
runtime/config.php仍保留旧值,改完.env也白搭 - CLI 命令(如
php think migrate)未在入口中设置think\Env::set('APP_ENV', 'prod'),导致环境变量未加载
多应用模式下子应用配置不自动合并
开启 app_multi => true 后,app/admin/config/app.php 这类子应用配置不会提前加载进全局配置。
真实行为是:
- 只有路由命中
admin应用时,它的配置才被加载 - 子应用内读取
config('app.debug'),拿到的是app/admin/config/app.php的值,不是根目录下的 - 若想在主应用中预加载子应用配置,需手动调用
Config::load(),不能依赖自动合并 - 子应用的
.env不支持独立加载——所有环境变量统一由根目录.env提供
最常被忽略的一点:配置项是否真正被框架识别,取决于它是否出现在加载链的某个环节里。比如把自定义配置写进 config/custom.php,却不调用 Config::load() 显式注册,那它永远是“存在但不可见”的状态。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











