I want to create array which follows the format below in order to create a dynamic menu in PHP.
$array = [
[\'id\'=>1, \'childs\'=>[]],
[\'id\'
Though you put in no effort into solving your issue, I will answer this because it's a difficult task to accomplish if you are not familiar with some concepts. I also understand your question to not mean "dynamic" so much as it's not hardcoded.
Firstly, the end product is not exactly what you are showing, but it's somewhat redundant how you have your expected output set up. By definition, a filled array under another array would be children ("childs") so there is no need to store them in a sub array called "childs".
To create this array you need to be able to create an array but then also traverse that same array as you are making it. You have to be careful with not making an orphaned child, meaning you have a id_parent
value, but no corresponding id
in your main array. It will not show up in the menu without extra script.
I have notated so viewers can understand what is happening instead of just blindly copying and pasting. One final note, I don't really take advantage of PHP's Object Oriented Recursive Array Iterator (or it's other iterator classes), so you should investigate those. You may be able to accomplish the same thing more efficiently:
# Main array with parents/children
$array = array(
array(
'id'=>1,
'id_parent'=>0
),
array(
'id'=>2,
'id_parent'=>0
),
array(
'id'=>3,
'id_parent'=>0
),
array(
'id'=>4,
'id_parent'=>0
),
array(
'id'=>5,
'id_parent'=>2
),
array(
'id'=>6,
'id_parent'=>2
),
array(
'id'=>7,
'id_parent'=>3
),
array(
'id'=>8,
'id_parent'=>7
),
array(
'id'=>9,
'id_parent'=>8
)
);
/*
** @description This function is a recursive iterator, meaning it will
** traverse the current array and all children
** @param $curr [string|int] This is the current id value being ready to place
** @param $parent [string|int] This is the current parent id being searched
** @param $arr [array] This is the array that is being built for the menu structure
** @param $array [array] This is the array pool of ids and parent ids. We are going to pass by reference
** to update this array as we go to fix chicken-before-the-egg scenarios
** @param $rKey [int] This is the current key being iterated on in the main array pool
*/
function recurse($curr,$parent,$arr,&$array,$rKey)
{
# Loop through our menu array to try and match parents
foreach($arr as $key => $value) {
# If there is a match
if($parent == $key) {
# Remove the key/value pair from main array
unset($array[$rKey]);
# Add the id to our menu array
$arr[$key][$curr] = array();
}
# If there is no immediate parent match
else {
# If the value is an array, try and now look through it for parent, else just continue
$arr[$key] = (is_array($value))? recurse($curr,$parent,$value,$array,$rKey) : $value;
}
}
# Send back this current array
return $arr;
}
/*
** @description This function takes your pool of ids and loops through them, sorting the menu items
*/
function getMenuArray($array)
{
# This is the final storage array
$arr = array();
# First count to see how many are available
$count = count($array);
# Start looping
for($i=0; $i<$count; $i++) {
$row = $array[$i];
# If there are no parents, the just assign base menu
if(empty($row['id_parent'])) {
$arr[$row['id']] = array();
# Remove this key/value pair from main array since it's been used
unset($array[$i]);
}
else {
# Recurse what we currently have stored for the menu
$new = recurse($row['id'],$row['id_parent'],$arr,$array,$i);
# If the recurse function didn't find it's parent
if(isset($array[$i])) {
# add it to the back of the array
$array[] = $row;
# Remove the current array
unset($array[$i]);
# Recount how many are left to iterate through
$count = count($array);
}
# If the parent was found
else
# Assign the $new array
$arr = $new;
}
}
# Return the array
return $arr;
}
print_r(getMenuArray($array));
Gives you:
Array
(
[1] => Array
(
)
[2] => Array
(
[5] => Array
(
)
[6] => Array
(
)
)
[3] => Array
(
[7] => Array
(
[8] => Array
(
[9] => Array
(
)
)
)
)
[4] => Array
(
)
)