Top

Building a Parent/Child Category Structure


PHP Code
+ 1 likes
Please Register to submit score.
Bookmark and Share
Average Score  8.3 (of 3 scores)
Date Added  Aug 20, 2004
Last Updated  Mar 19, 2007
Tags  category  datafeed  mysql  parentchild  tree 

Introduction

This generates two structures: a tree and a list of objects. Both are generated from the following standard parent/child database format:

- cat_id: primary key, auto_increment
- cat_title: name of category
- cat_parent_id: points to the cat_id of this items parent.

These are two recursive functions that first build a tree structure. The second recursive function builds a sortable list of objects with their full category path as shown below:
For Cat3: Cat1 > Cat2 > Cat3

It's helpful to use a print_r on both objects to get a visual idea of what you've built.

Important Notes:
- This code will not work without a query and a database.
- The parent category needs to be included in the dataset and $directory_id needs to match it's cat_id.


Grab the Code

/************************************************************/
// Category Item class
 
class category_item
{
    var $cat_id;
    var $depth;
    var $cat_title;
    var $cat_parent_id;
    var $cat_long_title;
 
    function category_item($cat_id, $depth, $cat_title, $cat_parent_id, $cat_long_title = '')
    {
        $this->cat_id = $cat_id;
        $this->depth = $depth;
        $this->cat_title = $cat_title;
        $this->cat_parent_id = $cat_parent_id;
        $this->cat_long_title = $cat_long_title;
    }
}
 
/*************************************************************/
// Builds the category list for the category select
 
$list = array();
 
function build_list($cat_array, $item = '', $depth = 0)
{
    global $template;
    global $list;
 
    foreach($cat_array as $category)
    {
        $loop_item = "$item$category[cat_title]";
 
        $category_item = new category_item($category[cat_id], $depth, $category[cat_title], $category[cat_parent_id], $loop_item);
        $list[] = $category_item;
 
        if(count($category[children]) > 0)
        {
            $depth++;
            build_list($category[children], $loop_item." > ", $depth);
            $depth--;
        }
 
        $loop_item = '';
    }
 
    return $list;
}
 
/*************************************************************/
// Adds the object to the children array of the object with 
// a cat_id equal to $parent_id
 
function tree_add($tree, $parent_id, $object, $cat_id)
{
    // Only start from the given cat_id, ignore all other roots
 
    if($parent_id == '0' and $object[cat_id] == $cat_id)
    {
        $tree[$object[cat_id]] = $object;
        return $tree;
    }
 
    if($tree)
    {
        foreach($tree as $key => $value)
        {
            $current = $tree[$key];
 
            // If this is the parent, add the object to it's children array
            if($current[cat_id] == $parent_id)
            {
                $tree[$key][children][$object[cat_id]] = $object;
            }
            else
            {
                // If it's not in this level, look a level deeper on the current object.
                $tree[$key][children] = tree_add($current[children], $parent_id, $object, $cat_id);
            }
        }
    }
 
    return $tree;
}
 
/*************************************************************/
// This pulls the data from the database.  This will not work without a
// database connection.  This code is compatible with the phpBB2 
// mySQL database class.
//
 
$query = "
    select
        *
    from
        categories
    order by
        cat_id
";
 
$result = $db->sql_query($query);
 
while($category = $db->sql_fetchrow($result))
{
    $children = array();
 
    $category[children] = $children;
 
    $cat_id = $category[cat_id];
    $cat_parent_id = $category[cat_parent_id];
 
    $cat_tree = tree_add($cat_tree, $cat_parent_id, $category, $cat_id);
}
 
$cat_list = build_list($cat_tree);
 

Comments

  (16)  RSS
Pauladao
Comments: 1
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Mar 22, 2006 12:39 pm
Hi Hawkee! This code is very usefull, but i'm getting an error while running it:

Warning: Invalid argument supplied for foreach() in c:\web\anuncios\admin\dump.php on line 35

Dump.php is what I named the script, the line with the error is:
foreach($cat_array as $category)

I tried to do something similar to this script myself, but I was not sucessfull. If you can see this and help figuring this error out, I would appreciate very much.

Best Regards;

(Marcio)
Hawkee
Comments: 1,039
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Mar 22, 2006 4:13 pm
It seems like your $cat_tree wasn't created properly. Make sure you check the data you're pulling from mySQL to be sure it's got a cat_title, cat_id and cat_parent_id for each category in your database.
rompers
Comments: 1
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Mar 18, 2007 11:03 pm
hello !

as now sql code should look

sorry for my bad english

thxRompers
Hawkee
Comments: 1,039
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Mar 19, 2007 2:38 am
rompers, what are you asking?
F*U*R*B*Y*
Comments: 637
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Mar 20, 2007 2:15 am
can you explain what this does please :) i don't really understand what you mean parent/child category structure
lostdeviant
Comments: 9
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Aug 26, 2008 11:21 am
Hawkee, Do you recommend any additional columns with the three you mentioned above for the "categories" table?

I'll be using categories with "breadcrumb navigation" on my sites. (at least I hope to)
Hawkee
Comments: 1,039
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Aug 26, 2008 11:48 am
Not necessarily. I added a field for the number of products in each category, but you'll have to create a script to calculate that number on a daily basis. Of course it's always important to have date, time and timestamp so you know when the category was created and last edited.
ejgeske
Comments: 4
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 11:04 am
It would be very helpful it you could add the database layouts.

Also, you only reference one database but you state we need to pull information from two.

In your class you state:
var $cat_id;
var $depth;
var $cat_title;
var $cat_parent_id;
var $cat_long_title;

It is hard to know which tables these belong to.
Also, in your $db->fetchrow(), is this a mysql_fetch_row, or mysql_fetch_object, assoc? Assuming you said row, im guessing it would be a fetch row, but clarification would be nice. Also, maybe a working script.
jonesy44
Comments: 1,856
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 11:19 am
$this->cat_id = $cat_id;

What does $this refer to?
And what the hell are "->"'s?
ejgeske
Comments: 4
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 12:05 pm
$this-> refers to the variables in the class ( "$this" means inside this or belongs to this object)

ejgeske
Comments: 4
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 12:17 pm
in the following example, i will assign some variables that belong to a class. But are assigned inside one of the function/methods. If you only assign it as $example and not as $this->example, it does not assign that variable to the entire class, only in that method/function.

class myClass
{
var $example;
var $example2;

function say_what()
{
$example = 'Hi';
$this->example2 = 'Hi again';


echo '$example: '.$example."<br/>";
echo '$example2: '.$example2."<br/>";
echo '$this->example: '.$this->example."<br/>";
echo '$this->example2: '.$this->example2."<br/>";
}
function say_again()
{
echo '$example: '.$example."<br/>";
echo '$example2: '.$example2."<br/>";
echo '$this->example: '.$this->example."<br/>";
echo '$this->example2: '.$this->example2."<br/>";
}
}


$convo = new myClass();
$convo->say_what();
$convo->say_again();

----------------
PRINT OUT
----------------

// this is $convo->say_what();
$example: Hi
$example2: //blank
$this->example: //blank
$this->example2: Hi again

// this is $convo->say_again();
$example: //blank
$example2: //blank
$this->example: //blank
$this->example2: Hi again // only this one assigned to class shows.
ejgeske
Comments: 4
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 12:18 pm
on the say again, only the variable that was assigned with $this is assigned to the class for later use by all of the functions.

this is object oriented php which became available with php5
jonesy44
Comments: 1,856
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 3:46 pm
righty.. i'll have a look into it. so basically $this->variable sets a string for ONLY that function?
Hawkee
Comments: 1,039
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Dec 5, 2008 4:09 pm
Thanks for the feedback ejgeske. I realize it's a bit confusing and difficult to implement. I wrote this years ago using the phpBB2 database class, so that explains the $db->sql_fetchrow. You have to download phpBB2 and grab the db/mysql.php and includes/db.php files to instigate the $db class. Or you could modify all the $db calls to work with your favorite database class.

There is only one table in this example. The "cat_long_title" doesn't even get used and isn't necessary at all. I'm not even sure why it made it into this snippet. The table only needs the following fields:

cat_id
cat_title
cat_parent_id

The depth is calculated in the code.

I hope this clears up any confusion and let me know if you have any luck with it.
fahad_se
Comments: 1
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Aug 29, 2009 5:43 am
no success, just time wasted
Hawkee
Comments: 1,039
 
PHP Snippet:  Building a Parent/Child Category Structure
Posted on Aug 30, 2009 10:46 am
fahad, what problems did you have? Maybe I can help.

Commenting Options

Register or Login to Hawkee.com or use your Facebook or Twitter account by clicking the corresponding button below.

  
Bottom