Multi-level recursive recursion in PHP

Admin   PHP   256  2020-08-12 08:42:24

We have some commonly used recursive formats as follows:

  •     Recursive display with the table in admin management
  •     Recursive display with the select tag in admin management
  •     Recursive with ul li tag in case of menu display

Although we subdivided into many categories actually we only use a single algorithm that is a recursive algorithm. And this algorithm we apply to both multi-level menus and multi-level categories.

First, we need to build a database to demo.

1. Create a database to store multi-level categories

For simplicity, I will build a database of three main fields that are id, title, and parent_id. Where id is the primary key and automatically increases, the title is the title of the category, and parent_id is the foreign key that points to the parent category. The case with the highest level will have parent_id = 0.

You create a demo database and a table of categories by running the following SQL code.

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
 
CREATE DATABASE `demo` ;
 
USE DATABASE `demo`;
 
 
CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=11 ;
 
INSERT INTO `categories` (`id`, `title`, `parent_id`) VALUES
(1, 'PHP', 0),
(2, 'JAVASCRIPT', 0),
(3, 'Codeigniter', 1),
(4, 'Phalcon', 1),
(5, 'Tutorials', 3),
(6, 'AngularJS', 2),
(7, 'jQuery', 2),
(8, 'Basic', 5),
(9, 'Advance', 5),
(10, 'Course', 3);

 

2. Analyze ideas to get data for recursion

Currently, there are many recursive tutorials online, but I find most of them use pure PHP and each recursion will take a query so the program runs very slowly.

Most of the current frameworks support Active Record database queries and the result it returns a numbered array from 0 -> n-1, so in this article instead of recursive and repeat the result. through the while loop and the function mysqli_fetch_assoc, we will perform through 2 steps:

Step 1: Get the list of categories from the database and put into an array, and this is the PHP code processing step 1:

$conn = mysqli_connect('localhost', 'root', 'vertrigo', 'demo');
 
$sql = 'SELECT * FROM categories';
 
$result = mysqli_query($conn, $sql);
 
$categories = array();
 
while ($row = mysqli_fetch_assoc($result)){
    $categories[] = $row;
}

Step 2: Recursively array the categories obtained in step 1. At this stage, we should delete the displayed element by using the unset function.

function showCategories($categories, $parent_id = 0, $char = '')
{
    foreach ($categories as $key => $item)
    {

        if ($item['parent_id'] == $parent_id)
        {

            // .....
            // .....
            // .....
           
   
            unset($categories[$key]);
            showCategories($categories, $item['id'], $char.'|---');
        }
    }
}

The next task of step 2 will be presented in the following sections.

3. Recursive multi-level section of table tags in admin

We have 3 steps, including 2 of the steps I mentioned above, so just post the code with the comments.

$conn = mysqli_connect('localhost', 'root', 'vertrigo', 'demo');
 
$sql = 'SELECT * FROM categories';
 
$result = mysqli_query($conn, $sql);
 
$categories = array();
 
while ($row = mysqli_fetch_assoc($result)){
    $categories[] = $row;
}
 
function showCategories($categories, $parent_id = 0, $char = '')
{
    foreach ($categories as $key => $item)
    {

        if ($item['parent_id'] == $parent_id)
        {
            echo '<tr>';
                echo '<td>';
                    echo $char . $item['title'];
                echo '</td>';
            echo '</tr>';
             
            unset($categories[$key]);
             
            showCategories($categories, $item['id'], $char.'|---');
        }
    }
}

The next step is to call the recursive function to display the category list.

<table border="1" cellspacing="0" cellpadding="5">
    <tr>
        <td><strong>Category</strong></td>
    </tr>
    <?php showCategories($categories); ?>
</table>

 

3. Recursive multi-level categories tab select option

For this form, we just need to adjust a bit in the forum display function.
 

function showCategories($categories, $parent_id = 0, $char = '')
{
    foreach ($categories as $key => $item)
    {
        if ($item['parent_id'] == $parent_id)
        {
            echo '<option value="'.$item[$key].'">';
                echo $char . $item['title'];
            echo '</option>';
             
            unset($categories[$key]);
            
            showCategories($categories, $item['id'], $char.'|---');
        }
    }
}

And here is the code to display the select tag for the forum:

<select>
    <?php showCategories($categories); ?>
</select>

 

4. Recursive multi-level categories with UL and LI tags

This function a little bit difficult because you will have to deal with the display time without a UL card. To accomplish this we must divide step 2 into two small steps as follows:

function showCategories($categories, $parent_id = 0, $char = '')
{

    $cate_child = array();
    foreach ($categories as $key => $item)
    {
   
        if ($item['parent_id'] == $parent_id)
        {
            $cate_child[] = $item;
            unset($categories[$key]);
        }
    }
     

    if ($cate_child)
    {
        echo '<ul>';
        foreach ($cate_child as $key => $item)
        {
 
            echo '<li>'.$item['title'];
             
    
            showCategories($categories, $item['id'], $char.'|---');
            echo '</li>';
        }
        echo '</ul>';
    }
}

And here is how to use:

<?php showCategories($categories); ?>

Another problem is that the class display handle for parent UL - LI tags and child UL - LI tags, to handle this case, we add a $stt parameter with the initial value = 0, and then each recursion will increase $stt to 1 unit. Now to check the level to add the class, just check the variable $stt.
 

function showCategories($categories, $parent_id = 0, $char = '', $stt = 0)
{

    $cate_child = array();
    
    foreach ($categories as $key => $item)
    {
        
        if ($item['parent_id'] == $parent_id)
        {
            $cate_child[] = $item;
            unset($categories[$key]);
        }
    }
     
 
    if ($cate_child)
    {
        if ($stt == 0){
            
        }
        else if ($stt == 1){
            
        }
        else if ($stt == 2){
           
        }
         
        echo '<ul>';
        foreach ($cate_child as $key => $item)
        {

            echo '<li>'.$item['title'];

            showCategories($categories, $item['id'], $char.'|---', ++$stt);
            echo '</li>';
        }
        echo '</ul>';
    }
}

 

Good Luck!