ThinkPHP多环境部署核心是环境变量驱动配置加载机制。需正确设置.env及.env.*文件、确保APP_ENV被识别、手动启用vlucas/phpdotenv加载对应环境文件,并将数据库等敏感配置按环境分离到独立文件中动态合并。

ThinkPHP 支持多环境部署的核心不是改一堆文件,而是建立「环境变量驱动配置加载」的机制。关键在于让 APP_ENV 真正生效,并通过它自动加载对应环境的专属配置,同时保持通用配置统一维护。
确保 .env 文件结构正确
项目根目录(与 app、config、public 同级)必须有以下文件:
-
.env:只放所有环境共用的变量,比如APP_NAME=MyApp、TIMEZONE=Asia/Shanghai -
.env.dev:仅开发环境变量,如APP_DEBUG=true、LOG_LEVEL=debug、REDIS_HOST=127.0.0.1 -
.env.test:仅测试环境变量,如APP_DEBUG=false、DATABASE_HOST=test-db.internal -
.env.prod:仅生产环境变量,如APP_DEBUG=false、DATABASE_HOST=rm-prod.mysql.rds.aliyuncs.com
⚠️ 所有 .env* 文件必须保存为 UTF-8 无 BOM 编码,否则 ThinkPHP 8 完全静默忽略,不报错也不加载。
让 APP_ENV 变量真正被框架识别
ThinkPHP 8 默认只读取系统级环境变量 APP_ENV(不是 .env 里的值),用于决定加载哪个 .env.* 文件。验证方式:
立即学习“PHP免费学习笔记(深入)”;
- CLI 启动时显式设置:
APP_ENV=prod php think run(Linux/macOS)或set APP_ENV=prod && php think run(Windows) - 在控制器中加
dump(getenv('APP_ENV'));,应输出"prod";若为false或空,说明 Web 服务器(Nginx/Apache)未透传该变量,或 CLI 启动路径不对 - Web 环境下,PHP-FPM 可能不继承 shell 环境变量,此时需在 Nginx 的
fastcgi_param或 PHP-FPM pool 配置中显式添加env[APP_ENV] = prod
手动启用 .env.* 多环境文件加载
ThinkPHP 原生只加载 .env,不支持自动匹配 .env.dev 等。必须在 public/index.php 中引入 vlucas/phpdotenv 并指定文件:
- 确认已通过 Composer 安装:
composer require vlucas/phpdotenv - 在
require __DIR__.'/../vendor/autoload.php';后插入:
if (!getenv('APP_ENV')) {
putenv('APP_ENV=' . ($_SERVER['APP_ENV'] ?? 'production'));
}
$envFile = __DIR__ . '/../.env.' . getenv('APP_ENV');
if (is_file($envFile)) {
Dotenv\Dotenv::createImmutable(__DIR__ . '/..', basename($envFile))->load();
}✅ 加载后,所有 .env.* 中的变量均可通过 env('REDIS_HOST') 或 Config::get('database.hostname') 获取。
数据库等敏感配置按环境分离
不要在 config/database.php 里写死连接信息。推荐做法:
-
config/database.php仅保留不变项:'type' => 'mysql'、'prefix' => 'tp_' - 创建
config/database_dev.php、config/database_prod.php,各写对应环境的'hostname'、'database'、'username'等 - 在
app/common.php中动态合并:if (is_file(CONF_PATH . 'database_' . APP_ENV . '.php')) {<br> Config::set(include CONF_PATH . 'database_' . APP_ENV . '.php', 'database');<br> }
这样既避免硬编码泄露风险,又保证运行时配置精准生效——改完记得执行 php think optimize:config 清除配置缓存。



















