PHP如何通过指定键数组过滤重构非固定结构的多维JSON数据
PHP 多维JSON数组按指定规则过滤实现方案
原代码问题分析
- 递归调用参数顺序颠倒,导致规则和待处理数组逻辑完全错位
- 仅用
in_array判断键是否存在,无法识别嵌套规则的键(即规则数组中值为数组的键名) - 未处理嵌套层级的键匹配逻辑,无法跨层级拾取目标字段
正确实现代码
public function filter_multidimensional(array $array, array $keys) { $result = []; foreach ($keys as $k => $rule) { // 规则为字符串,属于平级要拾取的字段 if (is_int($k) && is_string($rule)) { // 先在当前层级查找 if (array_key_exists($rule, $array)) { $result[$rule] = $array[$rule]; continue; } // 当前层级未找到,递归遍历子数组查找,适配跨层级取字段需求 foreach ($array as $item) { if (is_array($item)) { $subResult = $this->filter_multidimensional($item, [$rule]); if (!empty($subResult)) { $result = array_merge($result, $subResult); break; } } } } else { // 规则为数组,属于嵌套过滤场景,$k为父级键名,$rule为子级过滤规则 $targetValue = null; // 先在当前层级查找父键 if (array_key_exists($k, $array)) { $targetValue = $array[$k]; } else { // 当前层级未找到,递归遍历子数组查找 foreach ($array as $item) { if (is_array($item) && array_key_exists($k, $item)) { $targetValue = $item[$k]; break; } } } if ($targetValue && is_array($targetValue)) { $result[$k] = $this->filter_multidimensional($targetValue, $rule); } } } return $result; }
调用示例
首先将输入的JSON转为数组后调用方法:
// 原始JSON转数组 $jsonRaw = '{ "message": "User Detail", "code": 200, "error": false, "results": { "user": { "id": 2, "name": "ali", "country": { "id": 50, "name": "EGY" } }, "access_token": "=PQLkHJYIXB2uKbCq4sXIjD2GpBU2o" } }'; $jsonArr = json_decode($jsonRaw, true); // 过滤规则 $filterKeys = [ 'code', 'user' => [ 'id', 'country' => ['name'] ] ]; // 执行过滤 $filtered = $this->filter_multidimensional($jsonArr, $filterKeys); // 输出结果 echo json_encode($filtered, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
输出结果
{ "code": 200, "user": { "id": 2, "country": { "name": "EGY" } } }
如果需要将国家名转为小写,可在拾取name字段的逻辑中自行添加转换处理即可。
内容的提问来源于stack exchange,提问作者A. El-zahaby
相关产品推荐
相关产品推荐

