PHP读取INI文件嵌套分段:无需显式指定数量的解决方案问询
解决INI重复分段读取为PHP数组的问题
问题背景
我想把包含重复分段的names.ini读取成PHP数组,能正常访问所有重复的分段,但用默认的parse_ini_file根本跑不起来——核心问题是INI原生不支持同名重复分段,后面的分段会直接覆盖前面的。目前我搞了个需要显式给分段加索引(比如person_1、person_2)的写法,但得提前知道分段数量,太麻烦,想找不用指定数量的靠谱方案。
原INI文件(无法正常读取重复分段)
[person] name = Alice age = 25 [person] name = Bob age = 30
原PHP代码(问题所在)
$iniArray = parse_ini_file('names.ini', true); print_r($iniArray); // 结果只保留最后一个[person],前面的直接丢了
现有方案(需显式指定数量,不够灵活)
这种写法得给每个分段加编号,比如[person_1]、[person_2],但必须提前知道有多少个分段:
修改后的INI
[person_1] name = Alice age = 25 [person_2] name = Bob age = 30
对应读取代码
$iniArray = parse_ini_file('names.ini', true); $people = []; foreach ($iniArray as $key => $value) { if (str_starts_with($key, 'person_')) { $people[] = $value; } } print_r($people);
无需指定数量的替代方案
方案1:自己写INI解析逻辑
直接读文件内容手动处理,兼容原INI的重复分段写法:
$content = file_get_contents('names.ini'); $lines = explode("\n", $content); $currentSection = null; $result = []; foreach ($lines as $line) { $line = trim($line); // 跳过空行和注释 if (empty($line) || str_starts_with($line, ';')) { continue; } // 匹配分段头 if (preg_match('/^\[(.*)\]$/', $line, $matches)) { $currentSection = $matches[1]; // 第一次遇到该分段就初始化数组,之后每次追加新条目 if (!isset($result[$currentSection])) { $result[$currentSection] = []; } $result[$currentSection][] = []; // 指向当前分段的最新条目,方便后续赋值 $currentEntry = &$result[$currentSection][array_key_last($result[$currentSection])]; continue; } // 处理键值对 if (str_contains($line, '=') && $currentSection !== null) { list($key, $value) = explode('=', $line, 2); $key = trim($key); $value = trim($value); $currentEntry[$key] = $value; } } print_r($result['person']); // 输出会包含Alice和Bob两个条目
方案2:换用JSON格式(更省心)
如果能换掉INI格式,JSON天生支持数组结构,完全没这种问题:
对应的names.json
{ "person": [ {"name": "Alice", "age": "25"}, {"name": "Bob", "age": "30"} ] }
PHP读取代码
$jsonContent = file_get_contents('names.json'); $data = json_decode($jsonContent, true); print_r($data['person']);
总结
- 自定义解析逻辑不用改现有INI结构,适合必须保留INI格式的场景
- JSON方案更简洁,避开了INI的语法限制,适合不需要死守INI的场景
内容的提问来源于stack exchange,提问作者Mike75
相关产品推荐
相关产品推荐

