商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > ThinkPHP 8.0 使用 Env 环境变量区分多环境配置【部署】

ThinkPHP 8.0 使用 Env 环境变量区分多环境配置【部署】

  发布于2026-07-15 阅读(0)

扫一扫,手机访问

在ThinkPHP 8.0项目里,用.env文件来区分开发、测试、生产环境是个很实用的做法,能避免硬编码带来的坑——比如上线时忘了把数据库地址从本地改成生产环境,或者调试模式还开着就直接暴露给用户,这些场景想想就头大。但这里有个关键点:必须让APP_ENV变量生效,且框架能正确识别,否则config/目录下那些环境专用的配置文件,压根不会加载。

ThinkPHP 8.0 使用 Env 环境变量区分多环境配置【部署】

准备多环境配置文件结构

在项目根目录(跟appconfigpublic同级)新建三个文件:.env.dev.env.test.env.prod。每个文件里只写当前环境专属的变量,别把通用配置也塞进去——通用项统一放在【.env】里,它会被所有环境默认加载。

举个例子,.env.dev的内容可以这样:

APP_DEBUG=true
LOG_LEVEL='debug'
REDIS_HOST=127.0.0.1

.env.prod则写成:

APP_DEBUG=false
LOG_LEVEL='error'
REDIS_HOST=redis-prod.internal

必须警惕的是:.env文件必须保存为UTF-8无BOM编码,否则ThinkPHP 8会完全静默忽略,不报错也不加载——这可以说是最容易被忽略的致命陷阱。

设置系统级 APP_ENV 变量并验证

ThinkPHP 8默认读取的是系统环境变量APP_ENV,而不是.env文件里的APP_ENV值,这一点要搞清楚。

Windows用户在CMD中这样启动:

set APP_ENV=dev && php think run

Linux/macOS用户则执行:

APP_ENV=test php think run

启动后,随便访问一个接口,在控制器里加上一行:dump(getenv('APP_ENV'));,页面应该输出字符串devtest。如果输出false或空字符串,说明系统变量没传入PHP进程——常见原因是Apache/Nginx没透传变量,或者CLI启动时没前置设置。

启用多环境自动加载机制

打开public/index.php,找到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();
}

这一步必须做:ThinkPHP 8原生只加载.env,不支持自动匹配.env.*,所以必须手动引入vlucas/phpdotenv并指定文件名,否则.env.dev这些文件永远不生效。

第三步:确认vendor/autoload.php已加载dotenv类库

如果提示Class 'Dotenv\Dotenv' not found,先执行:composer require vlucas/phpdotenv

在 database.php 中按环境动态配置数据库

方法一:直接使用env()函数读取

打开config/database.php,在'connections' → 'mysql'数组内,把'hostname'改为:'hostname' => env('DB_HOST', '127.0.0.1'),;同理设置'database''username''password'

方法二:用条件判断加载不同配置块(更清晰)

database.php顶部加上:

$env = env('APP_ENV', 'production');
switch ($env) {
    case 'dev': $dbConfig = ['hostname'=>'localhost','database'=>'tp_dev']; break;
    case 'test': $dbConfig = ['hostname'=>'10.0.2.10','database'=>'tp_test']; break;
    default: $dbConfig = ['hostname'=>'db-prod','database'=>'tp_prod'];
}

然后在connections.mysql中直接写:'hostname' => $dbConfig['hostname'], 'database' => $dbConfig['database'],

注意:不要在switch外部直接写$dbConfig['hostname'],PHP会报undefined variable错误。

清除缓存并验证环境变量是否注入成功

执行命令:php think optimize:config

这一步不可跳过:ThinkPHP 8的配置是缓存化的,即使.env.*database.php全部改对,不执行这个命令,框架仍然从runtime/cache/config下读旧值。

验证是否生效:在控制器中写

dump(env('DB_HOST'));
dump(config('database.connections.mysql.hostname'));

两个dump输出必须一致,且等于你当前APP_ENV对应.env.*文件中DB_HOST的值。如果第一个有值第二个为空,说明config/database.php没正确引用env();如果两个都为空,说明.env.*文件没被加载,或者APP_ENV设置错误。

本文转载于:https://www.php.cn/faq/2824182.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注