PHP读取INI文件最可靠方式是parse_ini_file('app.ini', true, INI_SCANNER_RAW),可保留节结构、避免值自动转换,并规避点号键名被转下划线等问题;若需完全控制键名,应手动逐行解析或预处理字符串。

PHP 读取 INI 文件最可靠的方式是 parse_ini_file(),但默认行为会丢弃键名中的点号(.)和数字开头的键,且不支持嵌套节——这恰恰是多数人踩坑的起点。
为什么 parse_ini_file() 读出来的数组结构不对?
默认情况下,parse_ini_file() 把 [database.host] 这类带点的键直接当作顶层键处理,然后自动把点转成下划线(变成 database_host),更糟的是,如果节名含数字(如 [v2.api]),它可能被跳过或解析异常。
解决方法是启用严格模式并手动处理节:
- 传入第二个参数
true:让函数按节分组返回多维数组,例如['database' => ['host' => '127.0.0.1']] - 传入第三个参数
INI_SCANNER_RAW:避免值被自动解析(比如把on变成true) - 不要依赖默认的键名转换——它不可控
示例:
$config = parse_ini_file('app.ini', true, INI_SCANNER_RAW);
立即学习“PHP免费学习笔记(深入)”;
如何安全读取含点号、短横线或数字开头的键?
INI 标准本身不禁止 .、- 或数字开头的键名,但 parse_ini_file() 的默认解析器会截断或重命名它们。真正能保留原始键名的,只有自己写解析逻辑,或者用 file() + 正则逐行处理。
推荐折中方案:在 INI 中避免使用这些字符;若无法修改配置源,改用 parse_ini_string() 配合字符串预处理:
- 先
file_get_contents()读原始内容 - 用正则把
database.host替换为database_host(或加引号包裹:"database.host") - 再传给
parse_ini_string(),并开启true和INI_SCANNER_RAW
注意:引号包裹的键名(如 "log.level")在 PHP 7.4+ 才被原生支持,旧版本仍会出错。
为什么修改了 INI 文件,parse_ini_file() 却没生效?
PHP 不会自动刷新 INI 缓存——尤其是当文件路径是相对路径,或脚本反复调用该函数时,容易因 realpath 缓存或 opcache 导致读到旧内容。
- 用
realpath()显式展开路径,避免软链接/符号链接干扰 - 开发期可加
clearstatcache(true, $file),但生产环境慎用 - opcache 启用时,
parse_ini_file()的结果可能被缓存(尤其在 CLI 模式下反复运行脚本时) - 更稳妥的做法:把配置读取封装成单例,首次加载后缓存到内存,而非每次重新解析
真正麻烦的不是语法怎么写,而是你没法假设 INI 文件的键名“符合预期”——哪怕它看起来只是个普通配置文件,只要涉及自动化部署、多环境或第三方集成,点号、大小写混用、空格缩进、BOM 头都可能让 parse_ini_file() 静默失败。



















