I have a table set up in mysql as follows:
I would like to create a sidebar category navigation with Parent category - subcategories - and possible third level categories which I have stored in another table.
I am trying to get them to display in a tree structure like so:
A Night Out
- Clubs and Societies
- Public houses
- Restaurants
- Taxis and Private Hire Vehicles
- Theatres and concert Halls
- Wine Bars
Accommodation
- Bed and Breakfast
- Guest Houses
- Holiday Accommodation
- Hotels
- Self Catering Accommodation
Agriculture
- Agricultural Machinery and Spares
- Agricultural Merchants
- Animal Feedstuffs
- Country Wear
- Dairies
etc
At the moment I am able to create the following:
using this code:
$dbc = mysql_connect($db_host,$db_user,$db_pass);
$sdb = mysql_select_db($db_database);
$query = 'SELECT category_name, subcategory_name FROM categories, subcategories WHERE subcategory_parent = category_name';
$result = mysql_query($query, $dbc)
or die (mysql_error($dbc));
while($row = mysql_fetch_array($result)) {
$catname = $row["category_name"];
$subcatname = $row["subcategory_name"];
echo "<li>$catname</li><ul><li>$subcatname</li></ul>";
}
I want to get the first level category to display only once with the subcategories in a list below them. Can anyone tell me the most efficient way to do this? I think I need to use foreach but am not sure.
The third level category table I have set up has the same structure as this table but is subsubcategory_id / subsubcategory_parent / subsubcategory_name.
I think you would need something along the lines of this:
There is probably a more efficient way of doing this, a lot of the guys here are far more knowledgeable in this field, but this should do the trick! You may also want to check, table names/column titles etc too, to make sure they match your database.
only output the
catname
when it changes. You will also need to order your query by category_name first.Edit: Just re-read the question fully and want to say that when it comes to hierarchical trees, using a parent/child (or category/sub/subsub) is not the best method. Although it does work, it usually requires multiple queries and recursive functions for display. A better approach is to use the nested set which is made for exactly this purpose.
I'd simplify the data structure if you want the possibility of many-layered sub-categories (which you've said you might). The best way I've found to do something like this is to do something slightly different with data:
Note: I'm only using the
sort_order
to sort on child nodes with the same parent.Now I'd create a really simple SQL query to just retrieve the data ordered by
parent_id
thensort_order
:Now comes the "fun" part ... because, really, what we want here is structured data so I'd pass the query into an XML DOMDocument() to create a structured category system.
Essentially you loop through the data and as you're doing that loop you create nodes with an id something like
node_{$category_id}
and you can then assign the child nodes to their parent in the right order. You can then use standard DOM navigation to retrieve the data tree you want.The biggest advantage with this is that you can start from any child node and walk back up the node tree to create your category list - which means you can have it expand and collapse.
I did write a far more detailed explanation recently; I can post a link to it if you'd like.