
本文介绍一种安全、可靠的方式,将标准 `.env` 文件(每行形如 `key=value`,支持含多个等号的值,如 base64 密钥)解析为 php 关联数组,避开 `parse_ini_file()` 的限制并避免执行风险。
.env 文件虽看似简单(纯文本、KEY=VALUE 格式),但直接使用 PHP 内置函数往往失败:parse_ini_file() 要求 INI 格式(需节区 [section]),而 include() 或 eval() 则存在严重安全风险(可能执行任意代码)。因此,推荐采用手动逐行解析策略——精准分割键值对,同时正确处理值中包含多个 = 的边界情况(如 APP_KEY=base64:xxx=yyy=zzz)。
以下是一个健壮、生产可用的解析函数:
function loadDotEnv($filepath): array
{
if (!is_readable($filepath)) {
throw new InvalidArgumentException("Cannot read .env file: {$filepath}");
}
$data = [];
$lines = file($filepath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$line = trim($line);
// 跳过注释行和空行
if (empty($line) || $line[0] === '#' || $line[0] === ';') {
continue;
}
// 查找第一个 '=' 位置,确保值部分可包含多个 '='
$pos = strpos($line, '=');
if ($pos === false) {
continue; // 无效行,跳过
}
$key = trim(substr($line, 0, $pos));
$value = trim(substr($line, $pos + 1));
// 可选:移除值两端的引号(兼容带单/双引号的写法,如 DB_NAME="my_app")
if (strlen($value) >= 2 &&
(($value[0] === '"' && $value[-1] === '"') ||
($value[0] === "'" && $value[-1] === "'"))) {
$value = substr($value, 1, -1);
}
$data[$key] = $value;
}
return $data;
}
// 使用示例
$env = loadDotEnv(__DIR__ . '/../../.env');
var_dump($env['APP_NAME']); // string(7) "Laravel"
var_dump($env['APP_KEY']); // string(44) "base64:WVS0jXq4FBEOHEt2+K3AxyLCvTgq5L/dMhiFd5HZg7Q="✅ 关键设计说明:
- 使用 file() 加载全部行,配合 FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES 自动过滤换行符与空行;
- 通过 strpos($line, '=') 定位首个等号,保证 APP_KEY=base64:xxx=yyy 等复杂值不被错误截断;
- 主动跳过以 # 或 ; 开头的注释行,提升兼容性;
- 支持可选的引号剥离逻辑(适配 DB_PASSWORD='secret!' 或 "dev" 写法),增强鲁棒性;
- 抛出明确异常而非静默失败,便于调试与错误追踪。
⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 切勿使用 include()、require() 或 eval() 加载 .env —— 用户可控内容可能注入恶意 PHP 代码;
- 生产环境应确保 .env 文件不在 Web 根目录可访问路径下(如放在 ../.env),防止泄露;
- 如需更高级功能(变量插值、多环境覆盖),建议集成成熟库如 vlucas/phpdotenv,但本方案轻量无依赖,适合快速嵌入或学习理解底层原理。
该方法兼顾安全性、可读性与实用性,是解析 .env 类配置文件的推荐实践。











