PHP如何获取多维数组各层级键名并拼接为下划线分隔格式
PHP提取多维数组叶子节点键路径(下划线拼接)实现方案
需求说明
需要提取多维数组所有叶子节点的完整键路径,每层键名用下划线拼接,数组嵌套层级为1-4层,所有键名均为字符串类型。
示例输入数组
$ini_config['aaa']['email']['main'] = 'me@name.com'; $ini_config['bbb']['email']['ccc'] = 'you@name.com'; $ini_config['bbb']['phone']['local'] = '800-555-1212'; $ini_config['bbb']['phone']['skype'] = '744-222-1234'; $ini_config['ccc']['phone']['main'] = 'domain.com'; $ini_config['ccc']['domain']['https'] = 'https://www.domain.com'; $ini_config['ccc']['fax'] = '744-222-1237';
期望输出
aaa_email_main bbb_email_ccc bbb_phone_local bbb_phone_skype ccc_phone_main ccc_domain_https ccc_fax
原有代码问题
原有实现用全局变量$full_key存储路径,遇到叶子节点就直接把全局变量清空,没有做路径回溯,处理完同层级的一个分支后,父级路径会丢失,导致同属一个父节点的其他分支拿不到上层前缀,输出结果不符合预期。
可直接运行的实现代码
放弃全局变量传值,把当前累积的路径作为递归参数传递,每次递归的路径状态独立,不会互相干扰:
<?php $ini_config = [ 'aaa' => [ 'email' => ['main' => 'me@name.com'] ], 'bbb' => [ 'email' => ['ccc' => 'you@name.com'], 'phone' => [ 'local' => '800-555-1212', 'skype' => '744-222-1234' ] ], 'ccc' => [ 'phone' => ['main' => 'domain.com'], 'domain' => ['https' => 'https://www.domain.com'], 'fax' => '744-222-1237' ] ]; function getJoinedKeys(array $arr, string $prefix = ''): array { $res = []; foreach ($arr as $k => $v) { $current = $prefix ? "{$prefix}_{$k}" : $k; if (is_array($v)) { $res = array_merge($res, getJoinedKeys($v, $current)); } else { $res[] = $current; } } return $res; } // 调用输出结果 $keyList = getJoinedKeys($ini_config); foreach ($keyList as $item) { echo $item . PHP_EOL; }
实现特性
- 无全局变量依赖,不会出现全局状态污染问题
- 支持1到N层任意嵌套的数组,不需要针对固定层级写特殊判断
- 自动处理下划线分隔符,不会出现首尾多余下划线的问题
- 结果以数组形式返回,方便后续做存储、过滤等二次处理
运行上述代码会完全输出期望的键名列表。
内容的提问来源于stack exchange,提问作者Frank Jance
相关产品推荐
相关产品推荐

