Simple Recursive PHP Tree Menu Example

by frank on October 23, 2006

in Featured, Scripts

Recursion. It can be a bit to get your head around at first but it can often create a lightweight, robust and elegant solution.

This is a pretty basic example of recursion using PHP which can display a list based tree of a catalogue or any sort of data which has parents, children and end nodes like products.

An example of recursion

For this example to work you need to have a database structure which has a table for categories and a table for products. Each product and category has a parent, with the root element having a parent of 0.

It is easiest to download the mysql dump of the two tables, the images for the tree and the php script for displaying the data in a tree from below:

Once you have created the database, the script will do all the rest. Basically the data will appear as a tree which will have as many branches as categories and as many nodes as products.

The script will happily extend to any number of categories and products (using recursion), but I did not write it with a lot of categories and products in mind so it may not perform well under large loads.

A (brief) explanation of a recursive function:

The core function of the script is actually pretty simple once you get a handle on it, all the extra javascript stuff is just to make it look cool.

The display_children() function gets all the children for the desired parent out of the database. It has a list of children at this point that it is going to loop through, but on the first iteration, when the function gets to the first child, it calls itself again to find any children for this first child – this is recursion.

So it has gone from the root of your hierarchical data (if you pass it a parent id of 0), it has gathered all the children for the root category, it starts looping through them but that process is interrupted* by calling the same function again to try and find any children for the child category that it is currently ‘looking at’.

*It is important to get the idea that the process of looping through all the children is only temporarily interrupted, php has these stored in the stack of things it has to do. So once the script has finished being interrupted (by calling itself) it will go back to looping through the original children.

The function gets interrupted several times, but we never have to worry about it forgetting to get back to the original task, that’s part of the beauty of recursion.

Tracking back up the stack recursively

After the function is called on a child category and it finds that this category does not in fact have any children categories under it it starts back on the process of looping through the rest of the children one layer up in the heirarchy and finding any of their categories.

Once the function has finished going through all the child categories for this parent it will go and find the products for this parent also, after this is achieved it can continue tracking back up the stack and continuing its business.

The Javascript to display the tree

The javascript is there so that we can click on the items of the tree to expand that node. Another function that the javascript fulfills is highlighting children which do not have any further child nodes or products and therefore do not need to be expanded.

This part is not quite finished as I tacked it on as a last measure and may need to change some of the structure of the outputted HTML in order for it to work completely. Currently it will highlight the node but it does not change the icon next to the node to show that it can’t be clicked on.

Feel free to give it a whirl and let me know what you think, feedback, criticism etc. etc. I was largely influenced by these smart guys when I started this little project so check out their site.

Update:
Tree menu .zip download should be working now.

Was this article useful?

rss feed icon

Email this article to yourself or...

rss feed icon

Subscribe to the RSS feed for more useful articles and tips.

Share this article with others

  • del.icio.us
  • Twitter
  • Reddit
  • StumbleUpon
  • Facebook
  • Digg
  • http://deadlytechnology.com/scripts/displaying-file-permissions-with-php/ deadlytechnology.com : Blog Archive » Displaying File Permissions with PHP

    [...] For whatever reason you may need to display file permissions for one of your websites. I have thrown together a very basic script which will recursively (yay recursion) navigate your filesystem and save the folder/filenames and their respective file permissions into an associative array. The script then displays the array very basically. Due to its simplicity this script is definitely not feature rich, but the opportunity is there to build on this script very easily. [...]

  • Ice-Heki

    Link to “Tree Menu” doesn’t work =|

  • http://www.ice-heki.com Ice-Heki

    Download “Tree Menu” doesn’t work!

  • http://deadlytechnology.com franktank

    Hey Ice-Heki, thanks for pointing that out bro, I think it should all be sorted out now, the link is at the bottom of the post, enjoy and let me know if you have any probs with it.

    Cheers mate.

  • http://www.ice-heki.com Ice-Heki

    Thanks, Franktank!

  • Audrey

    Thank you! I could not figure out how to display a recursive query with the proper nesting…your code was exactly what I needed. Thank you!!!

  • Audrey

    Hi, Thanks again for the great script!

    I have a followup question for you….

    Is there a way to modify the script to set cookies to remember which folders were open and which were closed from your last visit? Or an “display all/collapse all” option?

    Thanks for your consideration,
    Audrey

  • http://deadlytechnology.com frank

    Hi Audrey, Absolutely not a problem, thanks for the feedback.

    I haven’t looked at this script in a while actually and unfortunately I don’t have much time at the moment to really look into this.

    As far as setting a cookie, you can set cookies using javascript which may help to solve that one. There is an example of this in the test.php file of the splash page script download. I would guess you could set a cookie every time the onClick event is fired to display the children of an element. [http://deadlytechnology.com/scripts/php/using-a-splash-page/]

    Display all/collapse all, I would probably approach this by giving all the

      tags which have style=’display:none;’ another id, common to all of them, then try and use mootools to select all of those elements with that id, then toggle their display between none and block.
      [http://clientside.cnet.com/wiki/mootorial/03-addons#dom.js]

      Hope that helps, feel free to let me know how you get on.

      Cheers,
      Frank.

  • Audrey

    Hi Frank,

    I’m not much of a js programmer, but I will give it a try. Thanks for the leads and the great script!!!!

    Audrey

  • Audrey

    Hi Frank,

    I know you are busy and haven’t thought about this script for a while, but I’m hoping this is an easy one for you :)

    As the folder list gets long, each time you click open a folder, your viewport return to the top of the browser window, and you have to scroll down to keep clicking to the location you want.

    Do you think it’s possible to modify the js so that there is an anchor as part of the link/li, so that people do not have to keep scrolling up and down?

    Thanks,

    Audrey

  • Peter

    Hi, your script is ,excellenet.!!
    It is very helpfull. Can I ask you how to display records from categories from exact id (the records above this id will not be displayed), and the tree will be expanded (only the first level of records- if I wont to display list of categories and this list will be showed with possibiltiy of expandion) at first displaying? I tried to do it, but…without success…
    Thanks, Peter

  • http://deadlytechnology.com franktank

    Hi Audrey,

    Sorry, I missed this one. I’m not really sure but I think what you are describing should work and definitely worth a try. Adding anchors to the links should not pose a problem.

    Cheers,
    Frank.

  • http://deadlytechnology.com franktank

    Hi Peter,

    Sorry I’m not too sure what you want to do exactly. If you only want items that are children of a certain item you should be able to alter the database query to change the tree to be just this subset?

    Cheers,
    Frank.

  • santhosh

    Sir,

    i am new to php programming can u send me the databse used for this tree program . i have a project to display the categories,subcategories, sub asub categories and products as tree. and also i cant understand the link feild used in this program . please help me

  • http://www.compare66.co.uk Neil

    Hi

    I have used and adapted your recursive menu and used it in my site at compar66.co.uk

    Firstly – thanks for knowledge.
    It helped me a lot.

    Seconcdly – If you have time can you answer me a small question. In the recursive menu, in the mySql query
    ” $sql = sprintf(“SELECT product_name, product_id, product_link
    FROM products
    WHERE category_id = %d”,
    $parent);”

    what is the significance of ‘%d’

    the script works OK without it, and I have googled all sorts of questions and looked in quite a few books, and the MySql Manual is written for boffins by boffins, all I can find is references to the date function %d etc

    ALSO
    in http://deadlytechnology.com/scripts/simple-recursive-php-tree-menu-example/

    the text box at the bottom, the text should be white, same as the ‘Name’ ‘Website’ box, at the moment the text seems to be black, on a black background.
    A person cannot see what he/she is writing

    thanks for the info, and if you have time, thanks in advance for any answer

    best regards
    Neil

  • http://deadlytechnology.com franktank

    Hi Neil,

    Thanks for the comment, its great that you are using it on your site compare66.co.uk which I had a look at and is an excellent idea, good luck with it!

    To your question, the %d is actually part of the sprintf() function (http://www.php.net/manual/en/function.sprintf.php). It evaluates the argument as an integer.

    Cheers for alerting me to the fact that this comment box has near invisible text! I just changed the theme and stuff like this just falls through the cracks as you probably know.

    Cheers,
    Frank.

  • steve

    wondered how one would now connect a link to a child to view that childs contents.

  • http://deadlytechnology.com franktank

    Can’t remember exactly how my script works :-) you know how it is – this was a while ago. But, where ever I’m outputting the html for displaying titles for the child elements just change that html to include anchor tags and the link you want to use… HTH

  • latha

    The code is excellent ! Thanks for code.

  • http://abcphp.com/story/232 abcphp.com

    Simple Recursive PHP Tree Menu Example…

    Recursion. It can be a bit to get your head around at first but it can often create a lightweight, robust and elegant solution. This is a pretty basic example of recursion using PHP which can display a list based tree of a catalogue or any sort of data…

  • Marek

    Hi, thanks for good example. I make some corrections for saving actual tree status to Cookies and load it on page refresh. To use my version make table PRODUCTCATS with field – ID int (autoincrement), PRODID int, CATID int. This correction is for saving one product to more categories.

    you can download it on:
    http://rapidshare.com/files/300695851/cookietree.zip.html

  • A reader

    Next time, just put everything in one archive. Thanks anyway!

  • Michel

    Many thanks,

    just some minor suggestions:

    use name instead of category_name ( it’s ok for category_id )
    and use link instead of category_link and so on …

    only auto increment fileds which is PK should have table name as prefix. ( it’s not a rule, there just make codes simpler )

  • frank

    I actually agree with that convention, wrote this code a while back.

  • ubed khan

    hi sir,
    thanks so much
    your code is exactly what i needed

  • http://www.tasaristanbul.com realturk

    hi, thank you very much… i find it

  • http://www.tasaristanbul.com realturk

    icral?k i used my web site but not worked recursive menu :(

  • http://www.tasaristanbul.com realturk

    thanks, i made it….