thinkphp 的 production 环境配置需同时满足三要素:php 运行时存在 app_env=production 环境变量(非仅 .env 中定义)、config/production/ 目录严格小写存在、且 runtime/config.php 缓存已清除;.env 仅提供 env() 函数变量值,不决定环境,且其值优先级高于 config/production/ 下的同名配置。

config/production/ 目录只在 APP_ENV=production 时加载
ThinkPHP 不会自动根据 .env 里的 APP_ENV=production 就去读 config/production/ 下的文件——它只认 PHP 启动时已存在的环境变量。如果 Web 服务器(如 Nginx)没透传,或 CLI 命令没显式设置,框架压根不会加载这个目录。
常见错误现象:APP_ENV=production 写在 .env 里,但 config/production/app.php 中的 'debug' => false 没生效,页面仍显示错误详情。
- Nginx 需加
fastcgi_param APP_ENV production;;Apache 用SetEnv APP_ENV production - CLI 下必须写成
APP_ENV=production php think run,不能只改 .env - 目录名必须全小写且严格匹配:不是
prod、Production或PRODUCTION,只能是production -
config/production/下的文件(如database.php)只覆盖同名键,其余配置仍来自config/app.php或config/database.php
.env 文件不决定环境,只提供变量值
.env 的作用不是“切换环境”,而是给 env() 函数提供运行时变量值。它永远在 config/production/ 加载之后才参与覆盖——也就是说,config/production/database.php 里写的 'hostname' => 'rds.aliyuncs.com',仍会被 .env 里的 DB_HOST=10.0.1.5 覆盖。
-
.env必须放在项目根目录,UTF-8 无 BOM 编码,否则静默失效 - 格式必须严格:
DB_HOST=10.0.1.5✅,DB_HOST = 10.0.1.5❌(等号两侧不能有空格) - 含特殊字符(如
@、!)的值必须用单引号:DB_PASS='p@ss!2026'✅ - 变量名必须全大写+下划线:
DB_PORT✅,db_port或DB-PORT❌
config/production/database.php 里别硬编码,要继续调用 env()
很多人以为把数据库配置挪进 config/production/database.php 就能“彻底隔离”,结果上线后密码还是明文写在 PHP 文件里——这既不安全,也违背 ThinkPHP 的设计逻辑。
正确做法是:哪怕在 config/production/ 下,每个字段仍应通过 env() 读取,只是默认值可以更贴近生产场景:
'mysql' => [
'hostname' => env('DB_HOST', 'rds-prod.aliyuncs.com'),
'database' => env('DB_NAME', 'prod_db'),
'username' => env('DB_USER', 'prod_user'),
'password' => env('DB_PASS', ''),
'hostport' => env('DB_PORT', 3306),
],
- 这样既能利用
config/production/提供差异化基础值,又保留 .env 的最终覆盖权 - 敏感字段(如
DB_PASS)绝不写死,哪怕只在生产配置里写一次 - 如果生产密码来自密钥服务,可在
env('DB_PASS')为空时追加解密逻辑,但必须确保解密失败时返回空字符串,避免 config 加载中断
改完 .env 或 config/production/ 后,缓存必须清
ThinkPHP 把所有配置(包括 env() 执行结果)合并后写入 runtime/config.php。只要这个文件存在,改了 .env 或 config/production/ 都不会生效。
- 每次部署后必须执行:
php think clear:config或php think optimize:config - 手动删
runtime/config.php也行,但注意runtime/目录权限是否允许 PHP 进程重建它 -
config:clear不会重读 .env——它只删缓存,下次启动时才会重新解析 .env 和 config/ 目录 - 验证是否生效:在控制器里输出
env('DB_HOST'),而不是只看getenv('DB_HOST'),因为后者可能来自系统级环境变量而非 .env
最常被忽略的一点:APP_ENV 是开关,.env 是调料,config/production/ 是菜单——三者缺一不可,但顺序和时机错了,再对的配置也白搭。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











