ThinkPHP中.env配置生效需满足四点:配置文件中所有项必须显式调用env()并设默认值;.env格式严格(等号无空格、变量全大写、值含特殊字符需单引号包裹);确保未被系统环境变量(如APP_ENV)覆盖;修改后必须手动清除配置缓存。

env() 函数必须在配置文件里调用,不能在控制器里补救
很多人改完 .env 发现 config/database.php 里的数据库没变,就跑去控制器里写 env('DB_HOST') 测试——这只能证明环境变量“读得出来”,但不等于配置已生效。ThinkPHP 的配置加载是一次性的:App 初始化时把 config/ 下所有 PHP 文件(含 database.php)执行一遍,结果缓存起来。如果 database.php 里没用 env(),那它压根不会感知 .env 变更。
正确做法是确保所有配置项都显式调用 env() 并带默认值:
return [
'connections' => [
'mysql' => [
'hostname' => env('DB_HOST', '127.0.0.1'),
'database' => env('DB_NAME', ''),
'username' => env('DB_USER', 'root'),
'password' => env('DB_PWD', ''),
'hostport' => env('DB_PORT', 3306),
],
],
];- 别留着
'hostname' => '127.0.0.1'这种硬编码,否则.env改了也白改 -
env()第二个参数不是可选的——空字符串''比null安全得多,尤其对DB_PREFIX这类可能为空的字段 - 变量名必须全大写+下划线,
DB_PWD不能写成db_pwd或db_password,否则env('DB_PWD')返回false
.env 文件格式错一个空格,整个文件就静默失效
.env 由 vlucas/phpdotenv 解析,它对格式极其敏感,报错往往不提示具体哪行错了,而是直接 fallback 到默认值,或者抛出 Dotenv\Exception\InvalidPathException(其实跟路径无关)。
- 等号两侧**绝对不能有空格**:
DB_HOST = 127.0.0.1❌,必须写成DB_HOST=127.0.0.1✅ - 值含空格或特殊字符(如
@、!、#)必须用单引号包裹:DB_PWD='pass@123!'✅,双引号会被 shell 当作变量展开,不推荐 - 注释只能独占一行且以
#开头,前面不能有空格;DB_HOST=127.0.0.1 # local这种行末注释不支持 - 变量名只能是字母、数字、下划线,且不能以数字开头:
API_V1_URL✅,1API_URL❌
APP_ENV 被系统环境变量预设时,.env 直接被跳过
本地开发一切正常,一上服务器配置就“不生效”?大概率是 Nginx 或 CLI 启动时已经设置了 APP_ENV=prod。ThinkPHP 的逻辑是:只要 PHP 的 getenv('APP_ENV') 有值,就不再读取 .env 文件。
立即学习“PHP免费学习笔记(深入)”;
- 验证方式:在控制器里打印
getenv('APP_ENV')和env('APP_ENV'),两者不一致就说明被系统变量覆盖了 - 解决方法:在服务器上删掉全局
APP_ENV设置,比如 Nginx 的fastcgi_param APP_ENV '';,或 CLI 的export APP_ENV=清空 -
.env必须放在项目根目录(和think命令同级),不在config/下,也不支持.env.production自动加载——那是 Laravel 的行为,ThinkPHP 不认
改完 .env 一定要清配置缓存,否则永远看不到新值
ThinkPHP 把所有 PHP 配置文件(config/app.php、config/database.php 等)合并后写入 runtime/config.php。这个缓存文件不会随 .env 变更自动更新,哪怕你重启 PHP-FPM 或 Nginx 也没用。
- 开发时最简单:运行
php think clear:config - 手动删:删除
runtime/config/目录下的全部文件 - 临时关闭缓存(仅开发):在
config/app.php中设'config_cache' => false - 注意:有些 IDE 或编辑器会自动保存文件触发 reload,但 ThinkPHP 不监听文件变化,必须主动清缓存
真正容易被忽略的是:env() 的调用时机和配置缓存的耦合关系。不是 “改了就能用”,而是 “改了 → 重新执行 config 加载逻辑 → 刷新缓存”。任何一步断开,都会让环境变量看起来“失效”。



















