必须用.env文件隔离敏感配置:先禁用.git跟踪并清除历史记录,再用phpdotenv在yii初始化前加载,配置中需设getenv()默认值,.env.dist存模板,生产环境优先用系统变量,最后验证生效。

新手部署Yii2.0.55项目时,直接把数据库密码、API密钥写进代码或提交到Git仓库,等于给攻击者递上生产环境的钥匙;必须让.env文件既可用又不可见,且不随代码泄露。
第一步:禁止.git跟踪.env文件
在项目根目录执行 echo ".env" >> .gitignore,确保该行存在且未被注释。这一步漏掉,后续所有安全措施都归零。
【.env文件一旦被git commit过,仅删掉再加.gitignore无效】 Git历史里仍存明文密钥,需用git filter-repo --invert-paths --path .env彻底清除(操作前务必备份仓库)。
第二步:用vlucas/phpdotenv加载环境变量
运行 composer require vlucas/phpdotenv 安装依赖。
在 web/index.php 最顶部(require autoload之后、创建Application之前)插入:
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');<br>$dotenv->load();
这一步必须放在 Yii 初始化之前,否则 getenv('DB_HOST') 永远返回空——很多新手卡在这一步,调试半天发现配置没生效,其实是加载时机错了。
第三步:配置文件中兜底默认值
打开 config/main.php 或 config/db.php,所有 getenv() 调用必须带 fallback:
'dsn' => getenv('DB_DSN') ?: 'mysql:host=localhost;dbname=yii2basic',
'username' => getenv('DB_USER') ?: 'root',
'password' => (string)getenv('DB_PASSWORD'), // 强转字符串防null传入PDO报错
不设默认值的后果是:本地缺配、CI环境没挂载、拼错变量名,全都会导致白屏500,且错误日志里只显示“undefined index”,根本看不出哪一行崩了。
第四步:分离敏感配置与通用配置
方法一:用 .env 存敏感项,.env.dist 存示例模板
在项目根目录新建 .env.dist,内容为:
# 数据库<br>DB_DSN=mysql:host=db;dbname=myapp<br>DB_USER=appuser<br>DB_PASSWORD=your_strong_password<br><br># 应用<br>YII_DEBUG=true<br>YII_ENV=dev
部署时复制 .env.dist 为 .env,人工填入真实密钥——绝不在任何自动化脚本里 echo 密钥到 .env。
方法二:生产环境跳过 .env,改用系统级环境变量
Linux服务器上执行:export DB_DSN="mysql:host=prod-db;dbname=live",然后启动PHP-FPM;此时 getenv() 优先读系统变量,.env 文件可完全不上传。
注意:Apache + mod_php 下需在 vhost.conf 中用 SetEnv DB_DSN ... 显式注入,否则 PHP 无法读取系统环境变量。
第五步:验证是否生效
1. 在 web/index.php 末尾临时加一行:var_dump(getenv('DB_USER'));
2. 访问首页,确认输出是你填的用户名,不是 false 或空字符串。
3. 删除这行代码,上线前务必移除调试语句。











