如何在 PHP 中正确解析 .env 文件(格式为 KEY=VALUE)

11次阅读

如何在 PHP 中正确解析 .env 文件(格式为 KEY=VALUE)

本文介绍一种安全、健壮的 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免费学习笔记(深入)”;

text=ZqhQzanResources