parse_ini_file 默认扁平化节区、不自动转类型、不校验路径;需显式传 true 启用节结构,ini_scanner_typed 启用类型推断,ini_scanner_raw 禁用变量展开,路径须用 dir 绝对化。

parse_ini_file 能直接读 INI 文件转成数组,但默认不处理节区段、不自动转类型、不校验路径——用错参数或忽略安全限制,轻则读不出值,重则泄露密码。
为什么 parse_ini_file 读出来的键全混在一起?
因为默认 process_sections 是 false,所有节(如 [database])被扁平化合并了。比如:
[database] host = localhost port = 3306 [cache] enabled = true
调用 parse_ini_file('config.ini') 后,得到的是单层数组:['host' => 'localhost', 'port' => '3306', 'enabled' => 'true'],根本分不清哪个配置属于哪个模块。
- 要保留节结构,必须显式传
true:parse_ini_file('config.ini', true) - 此时返回二维数组:
$cfg['database']['host']才能准确访问 - 如果节名含数字(如
[v2]),PHP 会把它当整数键处理,$cfg[2]可能意外覆盖其他键
布尔值和数字为啥还是字符串?
默认扫描模式 INI_SCANNER_NORMAL 把所有值当字符串处理,哪怕写的是 debug = true 或 port = 3306,结果里 $cfg['debug'] 是字符串 "true",$cfg['port'] 是字符串 "3306"。
- 改用
INI_SCANNER_TYPED模式可启用基础类型推断:parse_ini_file('config.ini', true, INI_SCANNER_TYPED) -
"true"、"on"、"yes"→true;"false"、"off"、"no"→false;"null"→null;纯数字字符串 →int - 注意:
INI_SCANNER_TYPED从 PHP 5.6.1 开始支持,低版本会报错
读不到文件或返回 false 怎么排查?
parse_ini_file 失败只返回 false,不抛异常,也不报具体原因。常见卡点有:
- 路径是相对的,它先查当前工作目录(
getcwd()),再查include_path,不是按脚本所在目录找 —— 建议一律用__DIR__ . '/config.ini' - 文件权限不足或不存在,
file_exists()和is_readable()应该在调用前手动检查 - INI 文件里用了非法字符作键名,比如
{、|、~、!,会导致整行跳过,且无提示 - 值里含未引号包裹的空格或特殊符号(如
url = http://a.com/path?x=1&y=2),&会被截断 —— 必须用双引号包住:url = "http://a.com/path?x=1&y=2"
敏感配置(比如数据库密码)能放心用 parse_ini_file 吗?
不能默认放心。如果 INI 文件里写了 password = ${DB_PASS},而你又提前定义了常量 define('DB_PASS', 'secret123'),那 parse_ini_file 会把 ${DB_PASS} 替换为真实值并返回 —— 这在共享环境或日志中极危险。
- 禁用变量展开:加
INI_SCANNER_RAW模式,值原样返回,不解析任何变量或常量 - 永远不要对用户可控的 INI 内容调用
parse_ini_file,除非明确设为INI_SCANNER_RAW - 密码类字段建议移出 INI,改用环境变量(
$_ENV['DB_PASSWORD'])或单独加密文件
最易被忽略的是路径查找逻辑和 scanner_mode 的组合效果:同一份 INI 文件,用不同参数读出来可能完全不是一回事,而且没有任何警告提示。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











