ThinkPHP 的主配置必须放在项目根目录的 config.php 中,它是框架启动时唯一被提前加载的配置入口;database、cache 等硬依赖项若未在此定义,命令行功能将直接失效。

ThinkPHP 的配置文件不在 application/config 下——至少不能只靠它跑全场景,尤其命令行、迁移、多应用启动时会直接报错。
config.php 必须放在项目根目录
框架启动第一阶段就调用 think\App::initCommonConfig(),此时应用层还没初始化,config.php 是唯一被提前加载的入口。写在 application/config/database.php 里的数据库配置,网页请求能连上,但执行 php think migrate:run 或 php think make:model User 会提示“找不到数据库配置”。database、cache、log、app_debug 这些硬依赖项必须放在这里,否则命令行功能直接瘫痪。
常见错误现象:
-
php think migrate报错:SQLSTATE[HY000] [1045] Access denied for user ''@'localhost' -
Cache::store('redis')静默 fallback 到 file 驱动,且缓存路径写入失败 - 日志不落盘,或写进
runtime/log/外的未知路径
.env 文件优先级最高,但要用对函数
env() 函数在 config.php 加载阶段已就绪,但 $_ENV 和 getenv() 不可用——前者未初始化,后者在 PHP-FPM 下默认禁用,且不会自动类型转换(比如 APP_DEBUG=true 会被当字符串处理)。
立即学习“PHP免费学习笔记(深入)”;
正确写法示例:
'hostname' => env('DB_HOST', '127.0.0.1'),
'port' => (int) env('DB_PORT', 3306),
'password' => env('DB_PASSWORD', ''),
'debug' => filter_var(env('APP_DEBUG', 'false'), FILTER_VALIDATE_BOOLEAN),
注意:env() 返回的是字符串,端口必须强制转 int,布尔值必须用 filter_var 转换,不能直接写 true/false 字面量。
多环境配置别堆在 config.php 里硬判断
把 if (APP_ENV === 'prod') { ... } else { ... } 塞进 config.php 看似简单,但会导致配置不可复用、难以测试、git diff 混乱。推荐做法是拆出独立文件 + 启动时动态加载:
- 建立
config/dev.php、config/prod.php、config/test.php - 在
config.php末尾加一行:return array_merge(require 'config/' . env('APP_ENV', 'dev') . '.php', $config); - 部署时设环境变量:
APP_ENV=prod(Linux)或set APP_ENV=prod(Windows CMD)
这样既能保证敏感信息不出代码库,又能让 CI/CD 流水线按需注入配置,避免手改文件引发的线上事故。
database.php 等子文件只是“补充”,不是主配置源
很多人以为 config/database.php 是数据库配置的唯一位置,其实它只是被 config.php 主配置合并进去的子项。如果 config.php 里没定义 database 键,框架会回退到默认值,导致生产环境误连本地库。
关键点:
-
config/database.php只在config.php中显式return [..., 'database' => require 'database.php']时才生效 - ThinkPHP 6+ 默认不自动加载子文件,必须手动
require或用Config::load() - 路由配置更特殊:
route/app.php是唯一自动加载的路由文件,它不是配置,而是可执行逻辑,Route::import()引入的其他文件必须清缓存才能生效
真正容易被忽略的是:所有配置最终都要汇入 config.php 的返回数组,它才是整个生命周期的配置源头。哪怕你写了十个子文件,只要没被这个入口包含,就等于不存在。



















