
本文介绍一种安全、健壮的 php 方法,用于读取并解析无节标题的 `.env` 文件(如 `app_name=laravel`),将其转换为关联数组,特别处理含多个等号(如 base64 密钥)的值。
.env 文件虽常被误认为是标准 INI 文件,但其实际格式与 parse_ini_file() 所期望的 INI 语法并不兼容——后者要求显式节名(如 [section]),且对值中出现的多个 = 符号缺乏容错能力。因此,直接调用 parse_ini_file(‘../../.env’) 会返回 false;而 include() 则因 .env 非合法 php 代码导致语法错误或意外输出,完全不可取。
正确的做法是手动逐行解析:读取文件内容 → 跳过空行和注释 → 按首个 = 分割键与值 → 自动处理值中可能存在的额外等号(如 JWT 密钥、base64 字符串)。以下是一个生产就绪的解析函数:
function loadEnv($filepath) { if (!file_exists($filepath)) { throw new InvalidArgumentException("Environment file not found: {$filepath}"); } $data = []; $lines = file($filepath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { // 跳过注释行(以 # 开头) if (strpos(trim($line), '#') === 0) { continue; } // 查找第一个等号位置,确保 value 可包含多个 = $pos = strpos($line, '='); if ($pos === false) { continue; // 忽略不含 = 的无效行 } $key = trim(substr($line, 0, $pos)); $value = trim(substr($line, $pos + 1)); // 可选:移除 value 两端的引号(支持 "value" 或 'value') if (preg_match('/^["'](.*)["']$/', $value, $matches)) { $value = $matches[1]; } if ($key !== '') { $data[$key] = $value; } } return $data; } // 使用示例 $env = loadEnv(__DIR__ . '/../../.env'); var_dump($env['app_NAME']); // string(7) "laravel" var_dump($env['APP_KEY']); // string(44) "base64:WVS0jXq4FBEOHEt2+K3AxyLCvTgq5L/dMhiFd5HZg7Q="
注意事项:
- ✅ 始终校验文件存在性,避免静默失败;
- ✅ 自动跳过 # 开头的注释行,符合 .env 社区惯例;
- ✅ 使用 strpos() 定位首个 =,而非 explode(‘=’, $line, 2)(后者在无 = 时会触发警告,且未限制分割次数);
- ✅ 可选支持带引号的值(如 DB_PASSword=”pass=word“),提升兼容性;
- ⚠️ 生产环境切勿将 .env 文件置于 Web 可访问路径下,应放置于文档根目录之外,并通过 open_basedir 或 Web 服务器配置严格限制访问。
该方法轻量、可靠、无外部依赖,适用于 Laravel、symfony 等框架外的任意 PHP 项目,是加载环境变量的推荐实践。
立即学习“PHP免费学习笔记(深入)”;