本文目录导读:

在PHP项目中隐藏敏感配置信息(如数据库密码、API密钥、加密盐值等)是保障安全的核心实践,以下是几种主流且推荐的方法,按推荐程度排序:
使用环境变量(最推荐)
原理
将配置信息存储在服务器环境变量中,而非代码文件里。
实现方式
设置环境变量:
# Linux/Mac 临时设置 export DB_PASSWORD="your_secure_password" export API_KEY="sk-xxx" # 永久设置(在 ~/.bashrc 或 /etc/environment) echo 'export DB_PASSWORD="your_secure_password"' >> ~/.bashrc source ~/.bashrc
PHP 读取环境变量:
// config.php
define('DB_HOST', getenv('DB_HOST') ?: 'localhost');
define('DB_NAME', getenv('DB_NAME') ?: 'mydb');
define('DB_USER', getenv('DB_USER') ?: 'root');
define('DB_PASS', getenv('DB_PASS') ?: '');
define('API_KEY', getenv('API_KEY'));
// 使用
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
DB_USER,
DB_PASS
);
使用 Dotenv 库(.env 文件):
composer require vlucas/phpdotenv
// .env 文件(切勿提交到 Git)
DB_HOST=localhost
DB_NAME=mydb
DB_USER=root
DB_PASS=s3cr3t
API_KEY=sk-xxxxxxxx
// index.php
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
define('DB_PASS', $_ENV['DB_PASS']);
重要: 将 .env 添加到 .gitignore
.env .env.local .env.*.local
配置文件分离与权限控制
结构
project/
├── config/
│ ├── config.php # 公共配置
│ └── config.local.php # 敏感配置(被 .gitignore)
├── .gitignore
└── index.php
config.php:
// 公共配置,可提交
define('SITE_NAME', 'My App');
define('DEBUG', false);
// 加载本地配置
if (file_exists(__DIR__ . '/config.local.php')) {
require_once __DIR__ . '/config.local.php';
}
config.local.php:
// 敏感配置,不提交
define('DB_PASS', 's3cr3t');
define('API_KEY', 'sk-xxx');
.gitignore:
config.local.php *.local.php
文件权限设置:
# 禁止其他用户读取 chmod 640 config.local.php # 或更严格 chmod 600 config.local.php
使用密钥管理服务
适合微服务或云环境:
AWS Secrets Manager
use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
$client = new SecretsManagerClient([
'version' => 'latest',
'region' => 'us-east-1'
]);
try {
$result = $client->getSecretValue([
'SecretId' => 'prod/db/password'
]);
$secret = json_decode($result['SecretString'], true);
define('DB_PASS', $secret['password']);
} catch (AwsException $e) {
error_log("Failed to retrieve secret: " . $e->getMessage());
exit(1);
}
HashiCorp Vault
$vault = new VaultClient([
'base_uri' => 'https://vault.example.com',
'token' => getenv('VAULT_TOKEN')
]);
$secret = $vault->getSecret('secret/data/db');
define('DB_PASS', $secret['data']['data']['password']);
混淆与加密(防御性做法,非替代方案)
简单的混淆
// 不推荐!只是增加难度
define('DB_PASS', base64_decode('czNjcjN0'));
使用加密配置文件
// 加密文件(使用 openssl)
// openssl enc -aes-256-cbc -salt -in config.plain -out config.enc -k YourKey
function decryptConfig($encryptedFile, $key) {
$data = file_get_contents($encryptedFile);
$cipher = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($cipher);
$iv = substr($data, 0, $ivlen);
$encrypted = substr($data, $ivlen);
return openssl_decrypt($encrypted, $cipher, $key, OPENSSL_RAW_DATA, $iv);
}
$config = json_decode(decryptConfig('config.enc', getenv('CONFIG_KEY')), true);
define('DB_PASS', $config['db_password']);
平台特定的配置方式
Docker 环境
# docker-compose.yml
services:
app:
environment:
- DB_PASSWORD=${DB_PASSWORD}
- API_KEY=${API_KEY}
env_file:
- .env
Kubernetes Secrets
apiVersion: v1 kind: Secret metadata: name: db-secret type: Opaque data: password: czNjcjN0 # base64 encoded
云平台环境变量
- AWS Elastic Beanstalk: 通过 AWS 控制台设置
- Heroku:
heroku config:set DB_PASSWORD=xxx - Azure: 应用设置
| 做法 | 推荐度 | 说明 |
|---|---|---|
| 环境变量 + .env | 本地开发最佳,配合 .gitignore | |
| 密钥管理服务 | 生产环境,企业级 | |
| 配置文件分离 | 简单项目,配合权限控制 | |
| 配置文件加密 | 额外保护,非主要方案 | |
| 代码中硬编码 | 绝对禁止 |
关键提示
- 永远不要将敏感信息提交到版本控制(Git)
- 永远不要在代码中硬编码密钥
- 使用
.gitignore排除所有敏感文件 - 为不同环境(开发/测试/生产)使用不同的配置
- 定期轮换密钥和密码
- 记录敏感信息访问日志
- 遵循最小权限原则
选择哪种方法取决于你的项目规模、部署方式和安全需求,对于大多数 PHP 项目,环境变量 + .env 文件 是最平衡的解决方案。