0

I am trying to do nested categories main menus and submenus separetly. it was giving error :

Error: Maximum function nesting level of '256' reached, aborting! ?

I have tried everything inthis answer: Solution for "Fatal error: Maximum function nesting level of '100' reached, aborting!" in PHP

But didnt work for me, now my page keep loading and keep adding black list dots to the page.

Here is code I think I am doing something wrong in codes but cant find where.

$sql = "SELECT * FROM categories";
$stmt =$pdo->prepare($sql);
$stmt->execute();
if($stmt->rowCount() > 0){
    $rows = $stmt->fetch();
}else{
    echo "Something went wrong";
}
unset($stmt);
$items = $rows;
echo "<ul>";
foreach($items as $item){
    if($item['parent_id'] == 0){
        echo "<li>".$item['cat_name'];
        $id = $item['cat_id'];
        sub($items, $id);
        echo "</li>";
    }
}
echo "</ul>";

function sub($items, $id){
echo "<ul>";
    foreach($items as $item){
        if($item['parent_id'] == $id){
            echo "<li>".$item['cat_name'];
            sub($items, $item['cat_id']);
        echo "</li>";
        }
    }
echo "</ul>";
}

I am using wamp server on local.

EDIT : Here is mytable structure, and I am usningphp 7.2.18

CREATE TABLE IF NOT EXISTS `categories` (
  `cat_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `cat_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  `seo_url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `parent_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `place` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`cat_id`),
  UNIQUE KEY `unique` (`cat_name`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Here i the data inmy data base:

INSERT INTO `categories` (`cat_id`, `cat_name`, `seo_url`, `parent_id`, `place`) VALUES
(1, 'Ana Sayfa', '#', 0, 1),
(2, 'Tutorials', '#', 0, 1),
(3, 'Java', 'java', 6, 1),
(4, 'Liferay', 'liferay', 3, 1),
(5, 'Frameworks', '#', 0, 1),
(6, 'JSF', 'jsf', 5, 1),
(7, 'Struts', 'struts', 5, 1),
(8, 'Spring', 'spring', 6, 1),
(9, 'Hibernate', 'hibernate', 6, 1),
(10, 'Webservices', '#', 0, 1),
(11, 'REST', 'rest', 10, 1),
(12, 'SOAP', 'soap', 10, 1),
(13, 'Contact', 'contact', 0, 1),
(14, 'About', 'about', 0, 1),
(15, 'TEST-TEST-TEST', 'test', 5, 1),
(16, 'TEST2', 'test2', 15, 1);
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345

1 Answers1

0

You do have one issue in your code, which is that you should be using $stmt->fetchAll() to fetch all the data, rather than $stmt->fetch() which will only fetch one row. However your list generation code works fine (https://3v4l.org/HPP3s) although it does produce some empty <ul></ul> structures. You can simplify this code and remove those by using this function. By passing $parent_id = 0 for the first iteration we avoid the need to have two separate blocks of code as you do.

function draw_menu($items, $parent_id) {
    echo "\n<ul>\n";
    foreach ($items as $item) {
        if ($item['parent_id'] == $parent_id) {
            echo "<li>" . $item['cat_name'];
            // any children?
            if (count(array_keys(array_column($items, 'parent_id'), $item['cat_id']))) {
                draw_menu($items, $item['cat_id']);
            }
            echo "</li>\n";
        }
    }
    echo "</ul>\n";
}

draw_menu($items, 0);

Demo on 3v4l.org

The output of this function for your sample data is as below:

<ul>
<li>Ana Sayfa</li>
<li>Tutorials</li>
<li>Frameworks
<ul>
<li>JSF
<ul>
<li>Java
<ul>
<li>Liferay</li>
</ul>
</li>
<li>Spring</li>
<li>Hibernate</li>
</ul>
</li>
<li>Struts</li>
<li>TEST-TEST-TEST
<ul>
<li>TEST2</li>
</ul>
</li>
</ul>
</li>
<li>Webservices
<ul>
<li>REST</li>
<li>SOAP</li>
</ul>
</li>
<li>Contact</li>
<li>About</li>
</ul>
Nick
  • 138,499
  • 22
  • 57
  • 95
  • Got you thanks, the menu I have in site requires two different block like menus and submenus differently to add html checkbox etc, I will try your code. –  Nov 17 '19 at 23:31
  • @dilekkoç fair enough - that wasn't clear from your code and I always love to simplify! :-) Note that you might be able to achieve that requirement using CSS using `::before` or `::after` based on the class of the menu item – Nick Nov 17 '19 at 23:34
  • I need to read more about fetch and fetchAll .lol thank you so much. –  Nov 17 '19 at 23:42