0

I have the following array :

Array
(
    [0] => Array
        (
            [ID] => 1
            [PARENT] => 0
            [NAME] => Your first category
        )
    [1] => Array
        (
            [ID] => 2
            [PARENT] => 1
            [NAME] => Your first forum
        )
    [2] => Array
        (
            [ID] => 4
            [PARENT] => 1
            [NAME] => Another Forum
        )
    [3] => Array
        (
            [ID] => 5
            [PARENT] => 1
            [NAME] => Good Forum
        )
    [4] => Array
        (
            [ID] => 6
            [PARENT] => 0
            [NAME] => Top Forum
        )
    [5] => Array
        (
            [ID] => 7
            [PARENT] => 6
            [NAME] => Sub Forum #1
        )
    [6] => Array
        (
            [ID] => 9
            [PARENT] => 7
            [NAME] => Sub Forum #1-1
        )
    [7] => Array
        (
            [ID] => 10
            [PARENT] => 7
            [NAME] => Sub Forum #1-2
        )
    [8] => Array
        (
            [ID] => 8
            [PARENT] => 6
            [NAME] => Sub Forum #2
        )
)

OK Here I have the var_export result as requested :

array (
  0 => 
  array (
    'ID' => '1',
    'PARENT' => '0',
    'NAME' => 'Your first category',
  ),
  1 => 
  array (
    'ID' => '2',
    'PARENT' => '1',
    'NAME' => 'Your first forum',
  ),
  2 => 
  array (
    'ID' => '4',
    'PARENT' => '1',
    'NAME' => 'Another Forum',
  ),
  3 => 
  array (
    'ID' => '5',
    'PARENT' => '1',
    'NAME' => 'Good Forum',
  ),
  4 => 
  array (
    'ID' => '6',
    'PARENT' => '0',
    'NAME' => 'Top Forum',
  ),
  5 => 
  array (
    'ID' => '7',
    'PARENT' => '6',
    'NAME' => 'Sub Forum #1',
  ),
  6 => 
  array (
    'ID' => '9',
    'PARENT' => '7',
    'NAME' => 'Sub Forum #1-1',
  ),
  7 => 
  array (
    'ID' => '10',
    'PARENT' => '7',
    'NAME' => 'Sub Forum #1-2',
  ),
  8 => 
  array (
    'ID' => '8',
    'PARENT' => '6',
    'NAME' => 'Sub Forum #2',
  ),
)

Some of that arrays PARENT value corespond to another array ID value. That helps me to make them nested. But the question is: how can I create an HTML list that will look like that:

<ul>
    <li id="1">
        Your First Category
        <ul>
            <li id="2">
                Your First Forum
            </li>
            <li id="4">
                Another Forum
            </li>
            <li id="5">
                Good Forum
            </li>
        <ul>
    </li>
    <li id="6">
        Top Forum
        <ul>
            <li id="7">
                Sub Forum #1
                <ul>
                    <li id="9">
                        Sub Forum #1-1
                    </li>
                    <li id="10">
                        Sub Forum #1-2
                    </li>
                </ul>
            </li>
            <li id="7">
                Sub Forum #2
            </li>
        <ul>
    </li>
</ul>

Any idea please?

6
  • 1
    It would be so much easier, if you gave output var_export() instead of print_r()... Commented Oct 6, 2011 at 8:39
  • 1
    I'd rather convert the array to a proper nested form before converting it as HTML list. Commented Oct 6, 2011 at 8:46
  • This is what I need ! To change the array form in order to meed the HTML Layout in a later actions. I just display the HTML in order to show the form of the array that I need. Commented Oct 6, 2011 at 8:47
  • 1
    Instead of letting php number your array, use the ID column as the array key. Then getting a parent is a trivial array lookup. You will have to watch out for a recursive array where a parent of a parent is the child. Commented Oct 6, 2011 at 8:49
  • Can you please show me exactly what you mean ? It looks like a good idea but I have not get it at all ! :? Commented Oct 6, 2011 at 8:51

2 Answers 2

7

What I would do:

  1. group menu(?) items by their parent id - $menu[$parentID] = array($child, $child, ...)
  2. use recursive function for generating menu for each parent - makeMenu($menu, $parentID)

This will allow you to visit each node twice - first time, when reordering array, second time, when printing node. So it will work great with small as well as with large arrays.

Source:

$data = array(
    0 => array(
        'ID'     => '1',
        'PARENT' => '0',
        'NAME'   => 'Your first category',
    ),
    1 => array(
        'ID'     => '2',
        'PARENT' => '1',
        'NAME'   => 'Your first forum',
    ),
    2 => array(
        'ID'     => '4',
        'PARENT' => '1',
        'NAME'   => 'Another Forum',
    ),
    3 => array(
        'ID'     => '5',
        'PARENT' => '1',
        'NAME'   => 'Good Forum',
    ),
    4 => array(
        'ID'     => '6',
        'PARENT' => '0',
        'NAME'   => 'Top Forum',
    ),
    5 => array(
        'ID'     => '7',
        'PARENT' => '6',
        'NAME'   => 'Sub Forum #1',
    ),
    6 => array(
        'ID'     => '9',
        'PARENT' => '7',
        'NAME'   => 'Sub Forum #1-1',
    ),
    7 => array(
        'ID'     => '10',
        'PARENT' => '7',
        'NAME'   => 'Sub Forum #1-2',
    ),
    8 => array(
        'ID'     => '8',
        'PARENT' => '6',
        'NAME'   => 'Sub Forum #2',
    ),
);

// reorder array
$menu = array();
foreach ( $data as $item ) {
    $menu[$item['PARENT']][] = $item;
}

// print menu
function makeMenu($menu, $parentID) {
    $html = "<ul>";
    foreach ( $menu[$parentID] as $item ) {
        $html .= "<li id='{$item['ID']}'>{$item['NAME']}";
        if ( isset($menu[$item['ID']]) ) {
            $html .= makeMenu($menu, $item['ID']);
        }
        $html .= "</li>";
    }
    $html .= "</ul>";
    return $html;
}
echo makeMenu($menu, 0);

Output (added spacings manually):

<ul>
    <li id='1'>
        Your first category
        <ul>
            <li id='2'>Your first forum</li>
            <li id='4'>Another Forum</li>
            <li id='5'>Good Forum</li>
        </ul>
    </li>
    <li id='6'>
        Top Forum
        <ul>
            <li id='7'>Sub Forum #1
                <ul>
                    <li id='9'>Sub Forum #1-1</li>
                    <li id='10'>Sub Forum #1-2</li>
                </ul>
            </li>
            <li id='8'>Sub Forum #2</li>
        </ul>
    </li>
</ul>
Sign up to request clarification or add additional context in comments.

Comments

1
$new_arr = array();
foreach($arr as $data) $new_arr[$data['id']] = $data;

foreach($new_arr as $id => &$data) $data['parent'] =& $new_arr[$data['parent']];

Now you have a proper array structure.

But you may have to turn it inside out, since it's structured by child. But your output is by parent.

So instead of the second foreach I posted, do this:

foreach($new_arr as $id => $data) $new_arr[$data['parent']]['children'][] =& $data;

5 Comments

Thanks for that snippet ! I will try it now and I will answer here for the results ! :)
@Merianos, Do you need only one level of children ?
No I need more than One levels. What I like to do is to retrive all the categories and forums from phpBB as nested list
almost. You can now see here my next problem stackoverflow.com/questions/7673044/…
Note that I had a typo. I wrote &= instead of =&

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.