返回 2026-04-25
⚙️ 工程

PHP 中用 parse_ini_file() 解析 .env 文件的陷阱You can parse an .env file as an .ini with PHP - but there's a catch

shkspr.mobi·2026-04-25

虽然 PHP 的 parse_ini_file() 函数可用来解析 .env 文件,但两者在行为上存在细微差异。例如,.env 允许未引用的字符串和特殊字符,而 INI 格式要求严格语法,可能导致解析错误或安全漏洞。直接使用可能引发意外行为,建议改用专用库如 vlucas/phpdotenv。

Terence Eden

humble .env 文件是一种简单实用的持久化环境变量存储方式。只需将文件放到服务器上,PHP 脚本就能愉快地读取它。

但具体怎么读呢?PHP 有很多优秀的解析库。不过有没有更简单的方法?有!你可以使用 PHP 的 parse_ini_file() 函数,它能正常工作。

但是……

.env 和 .ini 文件在行为上有细微差别,这可能会让你对着电脑破口大骂。

来看这个例子:

# This is a comment
USERNAME="edent"

运行 $env = parse_ini_file(".env"); 你会得到一个数组,其中 USERNAME 被设置为 "edent"。太棒了!完美运行,可以发布了!

但再考虑一下:

# This is a comment
USERNAME="edent" # Don't use an @ symbol here.

它会告诉你用户名是 "edent# Don"

什么鬼?!

关键点来了:.ini 文件的注释字符不是 #,而是分号 ;

我再给你举几个会让解析出错的例子:

# Documentation at https:/example.com/?doc=123
DOCUMENTATION=123
# Set the password
PASSWORD=qwerty;789

最终得到的 PHP 数组是:

[
  '# Documentation at https:/example.com/?doc' => '123',
  'DOCUMENTATION' => '123',
  'PASSWORD' => 'qwerty',
];

解析 .ini 文件时,会忽略所有没有 = 号的行。同时,字面意义上的分号会被当作新注释的开始,直到它们被引号包围。

我的代码高亮器应该能显示它是如何被解析的:

# Documentation at https:/example.com/?doc=123
DOCUMENTATION=123
# Set the password
PASSWORD=qwerty;789

更糟的是,考虑这种情况:

# Set the "official" name
REALNAME="Arthur, King of the Britons"

这会立即报错:PHP Warning: syntax error, unexpected '"' in envtest on line 1

在伪注释中使用单引号是没问题的,但如果 ini 解析器看到没有等号的引号,就会直接崩溃。

我确信还有其他陷阱。例如,某些保留字和符号不能用作键名。

这会失败:

# Can we fix it? Yes we can!
FIX=true

它会因为感叹号而卡住。

解决方法(愚蠢的方式)

.env 文件的注释以井号开头。

.ini 文件的注释以分号开头。

所以,混合文件让注释同时以 #; 开头是完全合法的。

看,如果蠢但能用……

今天我们学到了什么?

  • 解析 .env 文件有正确和错误两种做法。
  • 错误的做法一开始能用,直到不能用为止。
  • 你最好还是用专门的解析器,而不是指望你的 .env 文件看起来像 .ini 就能蒙混过关。
  • 下周节目预告——为什么你不该把密码藏在 JPEG 文件里!

    需要完整排版与评论请前往来源站点阅读。