My Programming Tutorials

My Programming Tutorials

Multi Level Nested Category System in Codeigniter and MySql

Last updated on by , 55 comments

Hello, today we are going to discuss on multi level category system in CodeIgniter which is a very common and essential module or feature of any e-commerce websites or any website.

Creating nested category system is not as easy as you think, but it is not impossible too. Here I am going to deliver full step by step tutorial on how you can create such kind of module using Codeigniter & MySql.

How to create Multi Level Category System in Codeigniter

This module is based on the recursive function concept. So let’s get started to develop multi level nested category system, carefully read below steps mentioned.

I am assuming that you are familiar with CodeIgniter’s MVC structure, so I’m not going to explain what model and controller in CI are.

1. create the database structure for categories table and insert all the data as shown in below image

multi-level-category-system

SQL code for categories table, open SQL tab in PhpMyAdmin and run below code.


CREATE TABLE `categories` (
  `cat_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `cat_name` varchar(50) COLLATE latin1_general_ci NOT NULL,
  `parent_id` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

2. creating model functions


    public function get_categories(){

        $this->db->select('*');
        $this->db->from('categories');
        $this->db->where('parent_id', 0);

        $parent = $this->db->get();
        
        $categories = $parent->result();
        $i=0;
        foreach($categories as $p_cat){

            $categories[$i]->sub = $this->sub_categories($p_cat->cat_id);
            $i++;
        }
        return $categories;
    }

    public function sub_categories($id){

        $this->db->select('*');
        $this->db->from('categories');
        $this->db->where('parent_id', $id);

        $child = $this->db->get();
        $categories = $child->result();
        $i=0;
        foreach($categories as $p_cat){

            $categories[$i]->sub = $this->sub_categories($p_cat->cat_id);
            $i++;
        }
        return $categories;       
    }

3. creating controller function


    public function categories(){

        $this->load->model('model_categories');
	$data = $this->model_categories->get_categories();

	print_r($data);
    }

if you are done with everything right as I mentioned in this brief tutorial, then after running the controller’s “categories()” function should produce the following result-

multi-level-category-system

in controller “categories()” function the variable $data stores all the categories available in your categories table. As you can see $data is an array, you can easily parse this array into any multi level menu item or lists.

If you find this article helpful please don’t get shy to share this article with your friends.

You may also like

Author Info

Paritosh Pandey

He loves Technology

Advertisement
55 Responses
  1. Can says:

    Hello there
    First of all thank you for your letter, how can we foreach in a select in this usage?

  2. ashish says:

    hello admin,
    i want to display menu using this array. how can i do?
    Please reply.

    • Paritosh Pandey says:

      as all the data stored in "$data" variable (see step 3.), I'm using unordered list here you can use bootstrap menu as well.

      
      function fetch_menu($data){
      
      	foreach($data as $menu){
      
      		echo "<li>".$menu->cat_name."</li>";
      
      		if(!empty($menu->sub)){
      
      			echo "<ul>";
      
      			fetch_sub_menu($menu->sub);
      
      			echo "</ul>";
      		}
      
      	}
      
      }
      
      function fetch_sub_menu($sub_menu){
      
      	foreach($sub_menu as $menu){
      
      		echo "<li>".$menu->cat_name."</li>";
      		
      		if(!empty($menu->sub)){
      
      			echo "<ul>";
      
      			fetch_sub_menu($menu->sub);
      
      			echo "</ul>";
      		}		
      
      	}
      
      }
      
      echo "<ul>";
      fetch_menu($data);
      echo "</ul>";
      
      

      please let me know whether it is working or not

  3. tarik says:

    hello, thanks for the tutorial
    my english not well but i try to ask something.
    i add link my categories and when i select a categories i get related entries (categories->sub categories..) it is ok but i need pagination that result

  4. Kuldeep Singh says:

    It is multi level but not n level. I think if we want n level approach we need a recursive function.

  5. Palani says:

    Hi,
    I need to know the naming structure and how to insert this data dynamically…

  6. Rajesh says:

    Hi,
    I need to print based on the categories from different printers. how can i do..?
    Please reply.

  7. Rushi Shukla says:

    How to Edit Delete N Level categories Subcategories code-igniter. Please Send me the Code immediately.

  8. Md. Kowsar MAhmud says:

    Thanks you bro

  9. Kjell-Arne says:

    Hi!
    Thanks for sharing this. Helped me answering a few Q about category setup.
    I’m using Codeigniter to build a rather large application, and is about to start on a custom inventory/stock management.

    One question.
    How would you go about to get the main parent category from an entry registered under the, say.. third child category in an Sql statement?

    • Paritosh Pandey says:

      very simple but tricky task, try to check category’s parent_id until and unless it gets 0 (zero).

      because zero parent_id means the category doesn’t have any parent category coz it is a parent category itself

      • Kjell-Arne Neshagen says:

        Thank you!
        I’m just not sure if the best way is to do this in the code, or if there is an SQL statement to do it.

        I’ll try a bit and see what i come up with.

        Thanks again!

  10. khush says:

    hiiiii what this sub in $categories[$i]->sub

  11. sonu says:

    hiii can you help me out with the code of printing parent in front of child in a table. Thank you in advance.

    • Paritosh Pandey says:

      could you let me know with the level of your array please?

      • sonu says:

        it would be having n levels

        • Paritosh Pandey says:
          
          
          	function fetch_menu($data){
          
          		foreach($data as $menu){
          
          			echo "<tr>";
          
          			echo "<td>".$menu->cat_name."</td>";
          
          			echo "<td>";
          			if(!empty($menu->sub)){
          
          				echo "<table>";
          
          				fetch_sub_menu($menu->sub);
          
          				echo "</table>";
          			}
          			echo "</td>";
          
          			echo "</tr>";
          
          		}
          
          	}
          
          	function fetch_sub_menu($sub_menu){
          
          		foreach($sub_menu as $menu){
          
          			echo "<tr>";
          
          			echo "<td>".$menu->cat_name."</td>";
          			
          			echo "<td>";
          			if(!empty($menu->sub)){
          
          				echo "<table>";
          
          				fetch_sub_menu($menu->sub);
          
          				echo "</table>";
          			}
          			echo "</td>";
          
          			echo "</tr>";
          
          		}
          
          	}
          
          	echo "<table>";
          	fetch_menu($data);
          	echo "</table>";
          
          
          • sonu says:

            This is just printing data in table not giving parent child relation. What I was is for eg if i have data “animal->dog->huskey” and animal->cat. Then my table should be like
            dog->animal
            huskey->dog
            cat->animal.

            I want this in table format.

          • Paritosh Pandey says:

            for this, I’d require your JSON encoded array, it’ll help me to understand better.

          • sonu says:

            [{“category_id”:”1″,”name”:”animal”,”name_id”:”0″,”count”:[{“category_id”:”11″,”name”:”dog”,”name_id”:”1″,”count”:[{“category_id”:”24″,”name”:”golden retriever”,”name_id”:”11″,”count”:[]}]},{“category_id”:”29″,”name”:”cat”,”name_id”:”1″,”count”:[]},{“category_id”:”31″,”name”:”tiger”,”name_id”:”1″,”count”:[]}]},{“category_id”:”2″,”name”:”fruits”,”name_id”:”0″,”count”:[{“category_id”:”16″,”name”:”kiwi”,”name_id”:”2″,”count”:[{“category_id”:”25″,”name”:”Green”,”name_id”:”16″,”count”:[{“category_id”:”30″,”name”:”Color”,”name_id”:”25″,”count”:[{“category_id”:”47″,”name”:”xyz”,”name_id”:”30″,”count”:[]}]}]}]}]},{“category_id”:”13″,”name”:”movie”,”name_id”:”0″,”count”:[{“category_id”:”26″,”name”:”avengers”,”name_id”:”13″,”count”:[{“category_id”:”27″,”name”:”marvels studio”,”name_id”:”26″,”count”:[]},{“category_id”:”32″,”name”:”iron man”,”name_id”:”26″,”count”:[]},{“category_id”:”33″,”name”:”captain america”,”name_id”:”26″,”count”:[]},{“category_id”:”34″,”name”:”black widow”,”name_id”:”26″,”count”:[]},{“category_id”:”35″,”name”:”hulk”,”name_id”:”26″,”count”:[]},{“category_id”:”53″,”name”:”avengers”,”name_id”:”26″,”count”:[]}]}]},{“category_id”:”14″,”name”:”food”,”name_id”:”0″,”count”:[{“category_id”:”15″,”name”:”burger”,”name_id”:”14″,”count”:[]}]},{“category_id”:”17″,”name”:”Automobile”,”name_id”:”0″,”count”:[{“category_id”:”18″,”name”:”car”,”name_id”:”17″,”count”:[{“category_id”:”19″,”name”:”Ferrari”,”name_id”:”18″,”count”:[]}]}]},{“category_id”:”20″,”name”:”wheather”,”name_id”:”0″,”count”:[]},{“category_id”:”21″,”name”:”Electronics”,”name_id”:”0″,”count”:[{“category_id”:”22″,”name”:”mobile”,”name_id”:”21″,”count”:[{“category_id”:”23″,”name”:”moto g5 plus”,”name_id”:”22″,”count”:[]}]},{“category_id”:”36″,”name”:”TV”,”name_id”:”21″,”count”:[{“category_id”:”37″,”name”:”videocon”,”name_id”:”36″,”count”:[{“category_id”:”38″,”name”:”smart tv”,”name_id”:”37″,”count”:[{“category_id”:”39″,”name”:”you tube”,”name_id”:”38″,”count”:[]}]}]}]}]},{“category_id”:”42″,”name”:”shoes”,”name_id”:”0″,”count”:[{“category_id”:”45″,”name”:”keytoes”,”name_id”:”42″,”count”:[]}]},{“category_id”:”48″,”name”:”jewellery”,”name_id”:”0″,”count”:[{“category_id”:”49″,”name”:”gold”,”name_id”:”48″,”count”:[{“category_id”:”50″,”name”:”necklace”,”name_id”:”49″,”count”:[]},{“category_id”:”51″,”name”:”earrings”,”name_id”:”49″,”count”:[]}]},{“category_id”:”52″,”name”:”platinum”,”name_id”:”48″,”count”:[]}]}]

            This is my json encoded file. Please reply as soon as possible. Thank you.

  12. Staria says:

    Hi… i am totally new to codeigniter and this is the best tutorial i have found for categories… however, i have a question: how do we pass the data to the view or how do we call it where we want it to be? Any help is greatly appreciated! Thanks!

    • Paritosh Pandey says:

      in Controller

          public function categories(){
      
          	// load model
              $this->load->model('model_categories');
      
              // get category array from model
      	$data['categories'] = $this->model_categories->get_categories();
              
              // load view
      	$this->load->view('category', $data);
      
          }
      

      in model (Model_categories.php)

      public function get_categories(){
      
          $this->db->select('*');
          $this->db->from('categories');
          $this->db->where('parent_id', 0);
      
          $parent = $this->db->get();
          
          $categories = $parent->result();
          $i=0;
          foreach($categories as $p_cat){
      
              $categories[$i]->sub = $this->sub_categories($p_cat->cat_id);
              $i++;
          }
          return $categories;
      }
      
      public function sub_categories($id){
      
          $this->db->select('*');
          $this->db->from('categories');
          $this->db->where('parent_id', $id);
      
          $child = $this->db->get();
          $categories = $child->result();
          $i=0;
          foreach($categories as $p_cat){
      
              $categories[$i]->sub = $this->sub_categories($p_cat->cat_id);
              $i++;
          }
          return $categories;       
      }
      

      and in view (category.php) place these two function

      function fetch_menu($data){
      
          foreach($data as $menu){
      
              echo "<li>".$menu->cat_name."</li>";
      
              if(!empty($menu->sub)){
      
                  echo "<ul>";
      
                  fetch_sub_menu($menu->sub);
      
                  echo "</ul>";
              }
      
          }
      
      }
      
      function fetch_sub_menu($sub_menu){
      
          foreach($sub_menu as $menu){
      
              echo "<li>".$menu->cat_name."</li>";
              
              if(!empty($menu->sub)){
      
                  echo "<ul>";
      
                  fetch_sub_menu($menu->sub);
      
                  echo "</ul>";
              }       
      
          }
      
      }
      

      finally call fetch_menu($categories) function where you want your menu to be displayed.

  13. OG says:

    Hi,
    Thank you sharing your work.

    With this solution how would you resolve the URL situation for sub categories and sub sub categories?
    With friendly seo urls, how would you present the url/category-name/sub-cat/sub-sub-cat and how would the route file look like?

    Thank you

    • Paritosh Pandey says:

      .htaccess
      RewriteRule ^(.*)$ index.php?params=$1 [NC, QSA]

      http://url.com/index.php?params=param/value/param/value

      result would be
      http://url.com/params/param

  14. Ashish says:

    In my case i have two table one is for main category and another is for subcategory and the parent_id is foreign key in subcategory table so can you help me please that how can i receive the data in header and menu bar

    • Paritosh Pandey says:

      you could use my above solution in your case as well, you just have to change the table name in sub_categories function.

  15. Prashant Trivedi says:

    fetch result in a nested accordian, i am trying but some structure changed so unable help me…

  16. Mj says:

    Great Post! Thank you so much!

  17. swain says:

    Hi,
    Thank you sharing your work.
    in my case
    my output is :
    .Accessories (Parent)
    .Keyboard (Child from accessories parent)
    .HP keyboard
    .HP keyboard 123
    .HP keyboard 456

    but I need to put the parent category before every child like this

    .Accessories
    .Accessories => Keyboard
    .Accessories => Keyboard => HP keyboard
    .Accessories => Keyboard => HP keyboard => HP keyboard 123
    .Accessories=>Keyboard=> HP keyboard => HP keyboard 123 => HP keyboard 456

    how can i do it plz help

  18. salmankhan says:

    your code is working but i made two tables categories and sub categories so how will fitch data from both tables

  19. salman khan says:

    sir plz help me to do this plz two tables plz show me how to get sub categories by parent categories

    • Paritosh Pandey says:

      it is supposed to be very simple @salman, you just have to change the fetching table from “sub_categories” function

      
          public function get_categories(){
      
              $this->db->select('*');
              $this->db->from('categories');
              $this->db->where('parent_id', 0);
      
              $parent = $this->db->get();
              
              $categories = $parent->result();
              $i=0;
              foreach($categories as $p_cat){
      
                  $categories[$i]->sub = $this->sub_categories($p_cat->cat_id);
                  $i++;
              }
              return $categories;
          }
      
          public function sub_categories($id){
      
              $this->db->select('*');
              $this->db->from('sub_categories');
              $this->db->where('parent_id', $id);
      
              $child = $this->db->get();
              $categories = $child->result();
              $i=0;
              foreach($categories as $p_cat){
      
                  $categories[$i]->sub = $this->sub_categories($p_cat->cat_id);
                  $i++;
              }
              return $categories;       
          }
      
      

      have fun!

  20. salman khan says:

    sir i have another problem in pagination would u help me plz ??
    sir i am passing two parameters one is for to get record by id and second parameters is pagination so it show me this error plz help me.

    An uncaught Exception was encountered
    Type: ArgumentCountError

    Message: Too few arguments to function Home::displayByCategories(), 0 passed in C:\xampp\htdocs\ci\system\core\CodeIgniter.php on line 532 and exactly 1 expected

    Filename: C:\xampp\htdocs\ci\application\controllers\AOR\home.php

    Line Number: 136

    Backtrace:

    File: C:\xampp\htdocs\ci\index.php
    Line: 315
    Function: require_once

  21. Shankar says:

    I have 3 level deep menu items in my database.
    like I have the following table

    menu_id menu_name parent_id
    1 Home 0
    2 Web Development 0
    3 WordPress 0
    4 About Us 0
    5 AWS Admin 2
    6 PHP 2
    7 Javascript 2
    8 Elastic IP 5
    9 Load Balancing 5
    10 Cluster Index 5
    11 RDS DB 5
    12 Framwork Dev 6
    13 Ecommerc Dev 6
    14 CMS Devlopment 6
    15 News & Media 6

    I followed your code and and it works fine I appriciate your effort for that. but in my case I am not able to print the 3rd level on my screen it shows only two leve like parent and their child but not the grandchild of menus

    please help me to solve this problem. I am newbie to CI
    Thanks & Regards

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.