thinkphp 6.x 多环境配置需满足三要素:.env 文件必须 utf-8 无 bom、置于根目录并由 dotenv 显式加载;app_env 必须小写且严格匹配 config/ 子目录名(如 prod);框架先加载根配置再用 env() 动态覆盖变量。

ThinkPHP 6.x 的环境变量和多环境配置不是“放个 .env 就自动切换”,而是由加载时机、环境标识、目录结构三者共同决定。核心逻辑是:.env 提供变量值,APP_ENV 决定配置目录,两者配合才完整生效。
.env 文件必须正确加载才能起作用
框架默认不主动加载 .env,需手动引入 vlucas/phpdotenv 并在入口文件中执行加载:
- 确认已安装:运行
composer require vlucas/phpdotenv - 修改
public/index.php,在autoload.php后立即添加:$dotenv = Dotenv\Dotenv::createImmutable(__DIR__.'/..');<br>$dotenv->load();
- .env 必须放在项目根目录(与
app/、config/同级),编码为 UTF-8 无 BOM - 格式要严格:等号两侧不能有空格;含空格或特殊字符的值必须用单引号包裹,例如
DB_PASSWORD='p@ss#123' - 写完后执行
git rm --cached .env && echo ".env" >> .gitignore,防止敏感信息泄露
APP_ENV 是环境切换的开关,不是靠 .env 自动设置
.env 里的 APP_ENV=prod 不会触发环境切换——它只是个普通变量。真正起效的是在入口文件中显式设置:
- 在
public/index.php顶部(autoload.php之后、start.php之前)调用:think\Env::set('APP_ENV', 'prod'); - 该值必须是小写且完全匹配子目录名:如设为
'prod',则框架会加载config/prod/下的配置;'production'或'PROD'均无效 - CLI 模式下(如
php think migrate)同样需要在think入口脚本中设置,不能只依赖 .env - Nginx/FPM 环境中,若已通过
fastcgi_param APP_ENV prod;透传,框架将跳过 .env 中的 APP_ENV,直接使用服务器变量
多环境配置靠 config/ 子目录,不是靠多个 .env 文件
ThinkPHP 6.x 的多环境本质是「配置目录隔离」,不是「.env 文件切换」:
- 按
APP_ENV值创建对应子目录,例如config/dev/、config/prod/ - 每个子目录下放同名 PHP 配置文件(如
database.php、app.php),内容只写差异化项 - 框架自动合并:先加载根目录配置作兜底,再用子目录同名文件覆盖其中键值
- 数据库主机、端口、库名等易变项,应全部从
env()读取,例如:'hostname' => env('DB_HOST', '127.0.0.1') - 不要在配置文件顶层直接写
env('DB_HOST'),推荐用闭包方式延迟解析(TP6.1+ 支持)
敏感变量和动态行为统一走 env() + 条件判断
不需要为每个环境建一套路由或日志配置文件,用 env() 控制分支更轻量可靠:
- 路由定义中判断:
if ('dev' === env('APP_ENV')) { Route::rule(...); } - 缓存类型切换:
'type' => 'redis' === env('CACHE_TYPE') ? 'redis' : 'file' - 日志级别控制:
'level' => 'dev' === env('APP_ENV') ? 'debug' : 'error' - 第三方密钥、API 地址等敏感项,只出现在 .env,不在任何 PHP 配置文件中硬编码
- 所有
env()调用必须在配置文件中完成,控制器里调用Config::set()无效,因配置已冻结
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











