我正在开发一个在PHP 7.2上运行的JSON API。 API的功能之一是基本的“仅向我显示这些列”过滤器。我希望能够在无需手动处理路径中每个“级别”的情况下使其动态化。
我的第一种方法是仅支持五个深度的嵌套路径。这涵盖了大多数用例,并且已经运行了好几年。
/ api / request / stuff?column = col1-sub1-data2,col1-sub2
完整结构(可以是对象或数组,但如有必要,我可以强制转换为数组):
[
'col1' => [
'sub1' => [
'data1' => false,
'data2' => 'abc',
'data3' => 123
],
'sub2' => [
'other1' => true,
'data3' => 987
]
],
'col2' => [
]
]
这是我非常幼稚的方法的一个例子:
foreach ($columns as $column) {
$path = explode('-', $column);
if (!is_array($path) || empty($path)) {
continue;
}
$pathCount = count($path);
switch ($pathCount) {
case 0:
case 1:
/* Too shallow. These should be handled before this point anyway... */
continue 2;
case 2:
if (!isset($detailObject[ $path[ 0 ] ][ $path[ 1 ] ])
) {
continue 2;
}
$newArray[ $path[ 0 ] ][ $path[ 1 ] ] = $detailObject[ $path[ 0 ] ][ $path[ 1 ] ];
break;
case 3:
if (!isset($detailObject[ $path[ 0 ] ][ $path[ 1 ] ][ $path[ 2 ] ])
) {
continue 2;
}
$newArray[ $path[ 0 ] ][ $path[ 1 ] ][ $path[ 2 ] ] = $detailObject[ $path[ 0 ] ][ $path[ 1 ] ][ $path[ 2 ] ];
break;
}
}
API使用column参数处理数据并返回以下内容:
[
'col1' => [
'sub1' => [
'data2' => 'abc'
],
'sub2' => [
'other1' => true,
'data3' => 987
]
]
有没有办法动态产生此输出?
答案 0 :(得分:0)
对任意深度的嵌套结构执行操作几乎总是需要递归函数。
function filterPath($data, $path) {
$key = array_shift($path);
if( empty($path) ) {
return [$key => $data[$key]];
} else {
return [$key => filterPath($data[$key], $path) ];
}
}
function filterPaths($data, $paths) {
$out = [];
foreach($paths as $path) {
$out = array_merge_recursive($out, filterPath($data, $path));
}
return $out;
}
$data = [
'col1' => [
'sub1' => [
'data1' => false,
'data2' => 'abc',
'data3' => 123
],
'sub2' => [
'other1' => true,
'data3' => 987
]
],
'col2' => [
]
];
var_dump(
filterPaths($data, [
['col1', 'sub1', 'data1'],
['col1', 'sub1', 'data3'],
['col1', 'sub2'],
['col2']
])
);
输出:
array(2) {
["col1"]=> array(2) {
["sub1"]=> array(2) {
["data1"]=> bool(false)
["data3"]=> int(123)
}
["sub2"]=> array(2) {
["other1"]=> bool(true)
["data3"]=> int(987)
}
}
["col2"]=> array(0) {}
}