网址参数: -
/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai
你可以注意到有两个类似数组的字符串。我想将它们转换为数组['addr' => ['nation' => ['key' => ['sx' => China]]], ['city' => 'Shanghai']]
我试过了: -
$results = [];
$str = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai/';
$params = explode('/', $str);
if($params[0] == '') unset($params[0]);
while(key($params) !== null && current($params)) {
$key = current($params);
$value = next($params);
if(strpos($key, '[')) {
$sub_keys = explode('[', $key);
foreach($sub_keys as &$sub_key) {
$sub_key = trim($sub_key, ']');
}
$count = count($sub_keys);
$ref = &$results;
foreach($sub_keys as $k => $v) {
if($k == $count - 1) {
$ref[$v] = $value;
$ref = &$ref[$v];
} else {
$ref[$v] = $ref[$v] ?? [];
$ref = &$ref[$v];
}
}
} else {
$results[$key] = $value;
}
next($params);
}
var_dump($results);
有效。得到:
array(3) {
["name"]=> string(5) "Aario"
["gender"]=> string(4) "male"
["addr"]=> array(2) {
["nation"]=> array(1) {
["key"]=> array(1) {
["sx"]=> string(5) "China"
}
}
["city"]=> &string(8) "Shanghai" // please notice here
}
}
但我担心引用(&
)会犯错误。
有更好的方法吗?
答案 0 :(得分:1)
将其转换为查询字符串应该会产生简短的代码:
$str = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai/';
$query = array_reduce(
array_chunk(explode('/', trim($str, '/')), 2),
function ($string, $item) {
return $string . $item[0] . (isset($item[1]) ? '=' . $item[1] : '') . '&';
}
);
parse_str($query, $result);
答案 1 :(得分:0)
一些简单的正则表达式处理:
context.callbackWaitsForEmptyEventLoop = true;
allPromises = getDatafromDynamo();
allPromises.then(results => {
console.log('Results are', JSON.stringify(results));
context.callbackWaitsForEmptyEventLoop = false;
callback(null, 'DONE');
return;
}).catch((err) => {
console.log("Error occurred", err);
context.callbackWaitsForEmptyEventLoop = false;
callback(err);
});
$replacements = [
'addr' => [
'nation' => [
'key' => [
'sx' => 'China'
]
],
'city' => 'Shanghai'
]
];
$url = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai';
$result = preg_replace_callback('~[^/]+~', function (array $match) use ($replacements) {
if (preg_match_all('/\w+/', $match[0], $keys) > 1) {
return array_reduce($keys[0], function ($a, $k) { return $a[$k]; }, $replacements);
} else {
return $match[0];
}
}, $url);
var_dump($result);
请注意,我更改了您的string(53) "/name/Aario/gender/male/China/China/Shanghai/Shanghai"
数据,因为它与网址中的占位符不对应。
答案 2 :(得分:0)
尝试使用递归函数
$str = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai/';
$params = explode('/', $str);
if($params[0] == '') unset($params[0]);
$is_odd_pos = true;
$results = [];
function rec(&$array, $keys, $val){
$keys = array_values($keys);
if(count($keys) > 1){
$key = $keys[0];
if(!isset($array[$key]))
$array[$key] = [];
rec($array[$key], array_slice($keys, 1), $val);
return;
}
$array[$keys[0]] = $val;
}
foreach($params as $k => $value) {
if($k % 2 == 0){
$key = $params[$k - 1];
preg_match_all('/\[(\w+)\]/', $key, $matches);
if(count($matches[1]) == 0){
$results[$key] = $value;
continue;
}
$key = explode('[', $key, 2)[0];
if(!isset($results[$key]))
$results[$key] = [];
rec($results[$key], $matches[1], $value);
}
}
var_dump($results);