У меня есть этот пример массива:
$roles = [
"dashboard.read" => true,
"dashboard.section1.read" => true,
"members.member.create" => false,
"members.member.read" => true,
"members.member.view.update" => true,
"members.member.view.section2.delete" => false,
"members.member.view" => true
];
и мне нужен метод для преобразования массивов аналогичной структуры в этот результат:
$roles = [
"dashboard" => [
"read" => true,
"section1" => [
"read" => true
]
],
"members" => [
"member" => [
"create" => false,
"read" => true,
"view" => [
"update" => true,
"section2" => [
"delete" => false
],
true,
],
]
]
];
Я не могу понять, как это сделать.
Для решения вашего вопроса я воспринял это как сложную задачу. Я добавил все детали прямо в код:
// your defined roles, as stated above
$roles = [
"dashboard.read" => true,
"dashboard.section1.read" => true,
"members.member.create" => false,
"members.member.read" => true,
"members.member.view.update" => true,
"members.member.view.section2.delete" => false,
"members.member.view" => true
];
// the magic array, which will have all the results later
$magic = array();
// iterate trough all the roles
foreach($roles as $key => $value) {
// split the roles and reverse the array, so we can start with setting the value
$roleNamePart = array_reverse(explode(".", $key));
// this array is used to recursive create all the array in itself
$magicCreationArray = array();
// iterate trough those role name parts starting at the "bottom"foreach($roleNamePart as $keypart) {
// if it is empty, it is really the bottom and you can set the value right there
if(empty($magicCreationArray)) {
$magicCreationArray[$keypart] = $value;
// if its not, it must be something inbetween, go one level up. its needed to create a temporary value for this, i guess
} else {
$tmp = $magicCreationArray;
unset($magicCreationArray);
$magicCreationArray[$keypart] = $tmp;
}
}
// merge all the data to the magic array, use array_merge_recursive so it does not override for example "dashboard"$magic = array_merge_recursive($magic, $magicCreationArray);
}
// here you go fam
print_r($magic);
Надеюсь, я смогу помочь вам с этим.
Приятно читать: http://php.net/manual/en/function.array-merge-recursive.php
Это легко сделать с помощью ссылок на массивы:
$input = [
"dashboard.read" => true,
"dashboard.section1.read" => true,
"members.member.create" => false,
"members.member.read" => true,
"members.member.view.update" => true,
"members.member.view.section2.delete" => false,
"members.member.view" => true
];
$output = [];
foreach($input as $key => $value){
$pointer =& $output;
$keyParts = explode(".", $key);
foreach(array_slice($keyParts, 0, -1) as $part){
if(!isset($pointer[$part])) $pointer[$part] = [];
$pointer =& $pointer[$part];
// special case: If $key is a.b.c.d and a.b is already defined, convert the a.b value into an array
if(!is_array($pointer)) $pointer = [$pointer];
}
$name = array_slice($keyParts, -1)[0];
// special case: If $key is a.b and a.b.c.d is already defined, append to the array rather than overwriting it
if(isset($pointer[$name])) $pointer[$name][] = $value;
else $pointer[$name] = $value;
}
Результат испытаний:
{
"dashboard": {
"read": true,
"section1": {
"read": true
}
},
"members": {
"member": {
"create": false,
"read": true,
"view": {
"update": true,
"section2": {
"delete": false
},
"0": true
}
}
}
}
Постскриптум Я не понимал, что мне потребовалось 10 минут, чтобы отладить специальное условие о members.member.view