My Programming Tutorials

My Programming Tutorials

Multi Level Nested Category System in Codeigniter and MySql

Last updated on by , 79 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

79 responses to “Multi Level Nested Category System in Codeigniter and MySql”

  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

  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

  22. anil says:

    how to display all menu in view page in codeigniter i implemented but it gives erroe udefined data

  23. ROM says:

    Hello, first of all great tutorial. Secondly I am having problem in setting display, I want to show this in a dropdown(select menu). The similar example can be found when you create categories in wordpress.

  24. OraInfra says:

    Help Required:

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

    1. what is ->sub??
    Message: Attempt to assign property ‘sub’ of non-object
    getting error when i using same e.g only difference DlvChalanNo

    code is mention below:

    public function get_categories($ID,$AccountID,$BrokerID,$datestart,$dateend)
    {

    $this->db->select(‘DlvChallanID , CONCAT(FYType,FabricName,DIA,Gauge) AS DlvInfo,
    GROUP_CONCAT( DlvChallanID) AS DlvID’);
    $this->db->from(‘deliverychallan’);
    $this->db->where(‘CompanyID’,$AccountID);
    $this->db->where(‘PartyID’,$ID);
    $this->db->group_by(“DlvChallanID”);

    // $this->db->where(‘DlvChallanID’,6);

    // $this->db->BETWEEN(‘DlvChallanDate’,$datestart AND $dateend);

    // $rawdata = $this->db->get()->result_array();

    $parent = $this->db->get();

    $categories = $parent->result_array();

    // echo “”;
    // print_r($categories);
    //die();

    $i=0;
    foreach($categories as $p_cat)
    {

    // $categories[$i]->sub = $this->sub_categories($p_cat->DlvChallanID);
    $categories[$i]->sub = $this->sub_categories($p_cat->DlvChallanID);
    $i++;

    }
    return $categories;

    }

    public function sub_categories($id){

    $this->db->select(‘DlvChallanID AS DlvID, DlvChalanNo AS DlvInfo’);
    $this->db->from(‘deliveryview’);
    // $this->db->where(‘FIND_IN_SET(DlvChallanID, “.$DlvID.”)’);
    $this->db->where(‘DlvChallanID’,$id);

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

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

    • Paritosh Pandey says:

      using ->sub we’re setting up a new key in our object type array, which will be used to store child categories.
      normally result_array() returns result as an array not in objects.
      instead of result_array() you should use result().

  25. OraInfra says:

    Thanks got it, Kindly can share its view also because i am new

  26. Edanyildiz says:

    Hello. I am new to ci.
    First of all thank you for the recursive function, it helped me a lot.
    I am trying to understand how to list products in view.
    For example;
    I have a table with products, where product_category_id is connected to categories table on cat_id.
    So;
    When i click page for category, i want to display all products regarding to that category. So, this is confusing for me.
    For a main category i need to view all products, for sub category i need to view products in subcat.
    Can you give me an example how to deal with this?
    I mean a model function and controller function…
    Thanks.

  27. Edanyildiz says:

    Hello,

    Thanks for all the details about the recursive function. It helped me a lot for my menu.

    I am trying understand how to view products.
    I mean i have a table with products, where products_cat_id is related to categories.cat_id.

    I am trying to handle this situation;

    http://www.example.com/products/ -> view all products
    http://www.example.com/products/category -> view category products
    http://www.example.com/products/category/subcategory -> view subcategory products

    Could you please give me a clue about, controller functions and model ?
    (Especially the SQL query)

  28. Aya says:

    Hi,

    i’m trying to do a treeview folder structure. parent_id and it’s child_id are stored in the same table.
    parent_id default value set as 0. when i create a sub-folder then it’s root folder id store in parent_id field.
    i need to view this data in tree view structure.but could not create it.i need help on this situation. also i used file-explore jquery plugin for create view part. but i need to pass my data to this view. please help me on this part.
    thank you.

  29. QueenZha says:

    Hello,

    Can you add pagination in the product result?

  30. deep singh says:

    i just want to know how to show menubar on view page. how to use “function fetch_menu($data)” in view page.

  31. Jeff says:

    What a stellar post, l was looking all over for this, thanks a million mate!

  32. Tempest says:

    I have done what I did above but for that sub category can’t appear, is there any way to display it

  33. Muhammad Asif says:

    It was very helpful. Thanks

  34. Torben says:

    Thanks for this valueable post, but I’m not sure on how to generate an array out of this.

    My goal is to create sth like this:

    categories[0] = all level 1 categories
    categories[1] = all level 2 categories
    categories[2] = all level 3 categories

    etc.

    Is it possible with this recursive function?
    Can you tell me how?

Leave a Reply

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