PHP recursive menu with 1 query

There are a lot of methods how to fetch menu with submenus. But I will show you how to get all menu with submenu data from database in one query and make recursive display with PHP.

Table “menu” schema should look like this:

id parent_id title
73 0 MENU_73
74 73 MENU_73_74

When we fill the database with menu/submenu records we can get all records by query:

$query = mysql_query("SELECT * FROM menu");

After printing query results we should see:

Array
(
    [0] => Array
        (
            [id] => 73
            [parent_id] => 0
            [title] => MENU_73
        )

    [1] => Array
        (
            [id] => 74
            [parent_id] => 73
            [title] => MENU_73_74
        )

    [2] => Array
        (
            [id] => 75
            [parent_id] => 74
            [title] => MENU_73_74_75
        )

    [3] => Array
        (
            [id] => 76
            [parent_id] => 74
            [title] => MENU_73_74_76
        )

    [4] => Array
        (
            [id] => 77
            [parent_id] => 74
            [title] => MENU_73_74_77
        )

    [5] => Array
        (
            [id] => 78
            [parent_id] => 73
            [title] => MENU_73_78
        )

    [6] => Array
        (
            [id] => 79
            [parent_id] => 78
            [title] => MENU_73_78_79
        )

    [7] => Array
        (
            [id] => 80
            [parent_id] => 73
            [title] => MENU_73_80
        )

    [8] => Array
        (
            [id] => 84
            [parent_id] => 80
            [title] => MENU_73_80_84
        )

    [9] => Array
        (
            [id] => 85
            [parent_id] => 80
            [title] => MENU_73_80_85
        )

    [10] => Array
        (
            [id] => 81
            [parent_id] => 0
            [title] => MENU_81
        )

    [11] => Array
        (
            [id] => 82
            [parent_id] => 81
            [title] => MENU_81_82
        )

    [12] => Array
        (
            [id] => 83
            [parent_id] => 81
            [title] => MENU_81_83
        )

)

We want to get those result with assigned childrens to parent, so use this function to do that:

//$tree - menu data array
//$parent - 0
function formatTree($tree, $parent){
        $tree2 = array();
        foreach($tree as $i => $item){
            if($item['parent_id'] == $parent){
                $tree2[$item['id']] = $item;
                $tree2[$item['id']]['submenu'] = formatTree($tree, $item['id']);
            }
        }

        return $tree2;
    }

And the result of using recursive function:

Array
(
    [73] => Array
        (
            [id] => 73
            [parent_id] => 0
            [title] => MENU_73
            [submenu] => Array
                (
                    [74] => Array
                        (
                            [id] => 74
                            [parent_id] => 73
                            [title] => MENU_73_74
                            [submenu] => Array
                                (
                                    [75] => Array
                                        (
                                            [id] => 75
                                            [parent_id] => 74
                                            [title] => MENU_73_74_75
                                            [submenu] => Array
                                                (
                                                )

                                        )

                                    [76] => Array
                                        (
                                            [id] => 76
                                            [parent_id] => 74
                                            [title] => MENU_73_74_76
                                            [submenu] => Array
                                                (
                                                )

                                        )

                                    [77] => Array
                                        (
                                            [id] => 77
                                            [parent_id] => 74
                                            [title] => MENU_73_74_77
                                            [submenu] => Array
                                                (
                                                )

                                        )

                                )

                        )

                    [78] => Array
                        (
                            [id] => 78
                            [parent_id] => 73
                            [title] => MENU_73_78
                            [submenu] => Array
                                (
                                    [79] => Array
                                        (
                                            [id] => 79
                                            [parent_id] => 78
                                            [title] => MENU_73_78_79
                                            [submenu] => Array
                                                (
                                                )

                                        )

                                )

                        )

                    [80] => Array
                        (
                            [id] => 80
                            [parent_id] => 73
                            [title] => MENU_73_80
                            [submenu] => Array
                                (
                                    [84] => Array
                                        (
                                            [id] => 84
                                            [parent_id] => 80
                                            [title] => MENU_73_80_84
                                            [submenu] => Array
                                                (
                                                )

                                        )

                                    [85] => Array
                                        (
                                            [id] => 85
                                            [parent_id] => 80
                                            [title] => MENU_73_80_85
                                            [submenu] => Array
                                                (
                                                )

                                        )

                                )

                        )

                )

        )

    [81] => Array
        (
            [id] => 81
            [parent_id] => 0
            [title] => MENU_81
            [submenu] => Array
                (
                    [82] => Array
                        (
                            [id] => 82
                            [parent_id] => 81
                            [title] => MENU_81_82
                            [submenu] => Array
                                (
                                )

                        )

                    [83] => Array
                        (
                            [id] => 83
                            [parent_id] => 81
                            [title] => MENU_81_83
                            [submenu] => Array
                                (
                                )

                        )

                )

        )

)

Now it is easy to print this array to menu with submenu.