How to create a mysql php multi-level list navigation - php

Basically I want to be able to create a multi-level navigation (many sub navs). Obviously I know this will be done through creating lists with in each other but I am pretty stuck on the logic of displaying it correctly.
I have seen stuff regarding parent/children relationships but can't find anything that is efficient and easy to udnerstand.
I don't need to know how the HTML is built. Just how the php/mysql can generate the lists.
Hope you can help.
A

Here is code I used. It builds unordered list with unlimited level of subitems.
/*
* Table has 3 fields: `ID`, `PARENTID` and `NAME`
* `ID` is unique, `PARENTID` showing his parent node id.
* This function will go through it and build unordered list and call itself when needed to build subitems.
* $level argument used to define wich node's subitems to build. Default is 0 which is top level.
*/
function showMenu($level = 0) {
$result = mysql_query("SELECT * FROM `tbl_structure` WHERE `PARENTID` = ".$level);
echo "<ul>";
while ($node = mysql_fetch_array($result)) {
echo "<li>".$node['NAME'];
$hasChild = mysql_fetch_array(mysql_query("SELECT * FROM `tbl_structure` WHERE `PARENTID` = ".$node['ID'])) != null;
IF ($hasChild) {
showMenu($node['ID']);
}
echo "</li>";
}
echo "</ul>";
}
Hope that helps.

I think the most efficient would be to get all records in one go from the database and then build the hierarchical structure again in php.
So you would have a structure similar to this in your database:
id parent_id menu_item
Then you can get all items and use a recursive function to build a hierarchical array which you can loop through to get your menu, sub-menu, sub-sub-menu, etc. items. See this question and the top-two answers on how to re-build the structure.

If you mean the HTML it's like this:
<ul>
<li>
Title
<ul>
<li>Title</li>
<li>Title</li>
<li>Title</li>
</ul>
</li>
<li>Title</li>
<li>Title</li>
<li>Title</li>
</ul>

assuming you know how to create filled with the content of a mysql table
assuming you have the following tables : Universes > Categories > Markets > Segments
1) list the content of 'Universes' in a select. when the user picks, call another .php script and send it the id of the chosen Universe (using GET or POST)
2) list the content of 'Categories', WHERE idUniverses = the id you sent to the second script.
3) same for the Markets...
It's easier with AJAX.
need the code ?

Related

confused to make sitemap using php coding

I have created a CMS website, now I am trying to make site map with php coding, but the code which i have made is not complete. i.e It is not showing all the sub menu data.
Please look at this image . According to this image, I am having many other sub menu under Weight training(sub menu of Fitness Exercises) ,but they are not visible. Why they are not visibile?
Please guide/help me to solve this issue
My php code
foreach ($query_sitemap as $artrow) {
$datefromsql = $artrow->created_date;
$time = strtotime($datefromsql); ?>
<p>
<ul>
<?php echo '<b>'.$artrow->menu_name.'</b>'; ?>
<?php $submenucon=$this->menumodel->fetch_menu_byPid($artrow->id);//i.e select*from menu where parent_id=$mid
if (empty($submenucon)) { ?>
---
<?php
} else {
foreach ($submenucon as $subtrow) {
?>
<?php echo '<li style="color:gray;margin:">'.$subtrow->menu_name.'</li><br/>'; ?>
<?php
}
}
?>
</ul>
</p>
<?php
$i++;
}
} ?>
You're dealing with a tree structure here represented (in a most siplistic/naive way) in a database. So the first thing you should do is to build a tree-like structure based on returned rows and only then traverse it recrusively in order to display.
You can read more on parsing tree-like tables here:
Is it possible to query a tree structure table in MySQL in a single query, to any depth?
Implementing a hierarchical data structure in a database
What is the most efficient/elegant way to parse a flat table into a tree?

Dynamic navigation with php

Hi I am building a site directory and I'm having a little trouble understanding how to use the $_GET['page'] function
I understand you can use this to navigate across sites which are dynamically made, in fact I have a site which uses it currently but I did not create that set of code and don't understand the logic behind it..
I know how I will handle the navigation - the homepage will contain sites with a link to both their website and to a listing on my site. The listing url will contain the category and the ID of the site.
I want it to look like domain/category/siteid or like domain/index.php?cat=2&id=58
I understand I will probably need to use htaccess to change the url to look like the first example..
So anyway, the url will contain both the site ID and category which I want to then use to associate with the dynamically loaded page, with the relevant category and site listing.
This seems to be the standard way of loading pages in PHP but I've been unable to find a good guide on how to do it, I will also need to read the data from the url to make a database call so if anyone could explain how I can read the url to get the listing id and category it would be greatly appreciated!
Thanks a lot
Luke
You answered your question more or less yourself. The parameters from the URL are available in PHP in the $_GET array. For your example the category would be $_GET['cat'] (would return 2) and the ID would be $_GET['id'] (would return 58).
Take care of SQL-Injections. Also see other global variables
<ul>
<li>HOME</li>
<?
$first_query = "SELECT * FROM navigation_menu WHERE `status` ='active'";
$first_menu = $db->select($first_query);
for($a = 0 ; $a < count($first_menu) ; $a++)
{?>
<li> <?=$first_menu[$a]['navigation']?>
<?$second_query = "SELECT * FROM sub_menu WHERE nav_menu_id=".$first_menu[$a]['id']." AND `status` ='active'";
$second_menu = $db->select($second_query);
if(count($second_menu) > 0)
{?>
<ul>
<?for($b = 0 ; $b < count($second_menu) ; $b++)
{
if($second_menu[$b]['sub_nav_menu'] != '')
{?>
<li> <?=$second_menu[$b]['sub_nav_menu']?>
<?$third_query = "SELECT * FROM sub_child_menu WHERE nav_menu_id=".$first_menu[$a]['id']." AND sub_nav_id=".$second_menu[$b]['id']." AND `status` ='active'";
$third_menu = $db->select($third_query);
if(count($third_menu) > 0)
{?>
<ul>
<?
for($c = 0 ; $c < count($third_menu) ; $c++)
{?>
<li>
<a href="general.php?id=<?=$first_menu[$a]['id']?>&sid=<?=$second_menu[$b]['id']?>&cid=<?=$third_menu[$c]['id']?>&general=c">
<?=$third_menu[$c]['child_menu']?>
</a>
</li>
<?}?>
</ul>
<?}?>
</li>
<?}
}?>
</ul>
<?}?>
</li>
<?}?>
</ul>

PHP Menu - Loading from Database, can't get structure right

I'm having a hard time getting this menu to work properly.
function writeMenu(){
echo "<div id=\"menu\">" <ul id=\"top-link\">";
m("top", "n"); echo "</ul></div>"; (sorry, it wouldn't format properly)
function m($parent,$issub){
$parentQ = "select * from cdi_menu";//gets menu items from menu table
$parentResult = mysql_query($parentQ); //runs menu item query and obtains result
while ($link = mysql_fetch_assoc($parentResult)) {//for each line in the result do the folowing:
if($parent==$link['PARENT']){//if the next link belongs to this menu item
echo "\n <li>".$link['DISPLAY']."</li>";
if($issub=="n" && $link['HASCHILD']=="y"){//if this menu item is a top menu item
echo "\n <li id=\"sub-link\"><ul>";
m($link['ID'], $links, "y");
echo "\n </ul></li>";
}
}
}
}
echo writeMenu();
What I'm trying to do is make it where I can hide the 'sub-link' IDs (I would use classes, but javascript doesn't seem to edit class styles, just IDs). The sub-link items would show when over a parent item.
top refers to the top elements, and ID refers to the unique id in database.
Thanks, sorry if it's confusing.
Your function has only 2 parameters but You call it with 3 inside
m($link['ID'], $links, "y");
$links is unnecessary.
It would be better if You modify query to look like this
$parentQ = "select * from cdi_menu WHERE parent='$parent'";
so You don't need first if statement and You will not fetching all rows multiple times for each menu/submenu.

querying in hierarchical data-structure in database and displaying results

I thought to implement advanced commenting system in my website using PHP-MySql. I finally settled for a 3-level comment-reply system for this purpose.
Well, for that purpose I came across this article to implement the data-structure of the SQL database.
I planned to use nested set mdoel for the feature I want to use. The structure of the comments are like this-
<ul>
<li>Parent comment</li>
<ul>
<li>First reply of parent comment</li>
<ul>
<li>reply of the previous reply</li>
<ul>
<li>reply of the previous reply</li>
<li>another reply of the previous reply</li>
</ul>
<li>another reply of the previous comment</li>
</ul>
<li>second reply of the parent comment</li>
</ul>
</ul>
For this type of structure, I have been playing around with PHP to show the query detecting the parents and its child uniquely(for fetching user details associated with each comment) and produce the output in the manner if shown above. Do anyone have idea how to do it. Please help me out.
EDIT :
I have a seperate user table in SQL linked to the comment table as user.id=comment.id. So considering this, what would be the recommended approach to detect user activity for each comment? I mean, for ex- I want to fetch user name and email for a sub-comment of parent comment 2. Hoow could it be done?
Use the query from "Finding the Depth of the Nodes", and this PHP code will create the nested lists.
$cur_depth = -1;
while ($row = mysqli_fetch_assoc($query)) { // Loop through results of query
if ($row['depth'] > $cur_depth) {
echo "<ul>\n";
$cur_depth = $row['depth'];
}
else while ($cur_depth > $row['depth']) {
echo "</ul>\n";
$cur_depth--;
}
echo "<li>" . $row['comment'] . "</li>\n";
}
while ($cur_depth > -1) {
echo "</ul>\n";
$cur_depth--;
}

loop though a multi level array with an unknown amount of levels

I have a categories table that looks like this:
----------------------------------------
| id | parentId | Name |
----------------------------------------
1 0 Cat 1
2 0 Cat 2
3 0 Cat 3
4 2 Cat 4
5 3 Cat 5
6 5 Cat 6
Basically I need to iterate through the categorys creating a UL LI html list like the following:
<ul id="categories">
<li id="1">Cat 1</li>
<li id="2">Cat 2
<ul>
<li id="4">Cat 4</li>
</ul>
</li>
<li id="3">Cat 3
<ul>
<li id="5">Cat 5
<ul>
<li id="6">Cat 6</li>
</ul>
</li>
</ul>
</li>
</ul>
Im having major issues trying to iterate over this trying to create the above html. The id's maybe any number of levels deep within parentId's. Im donig this in PHP. Because there are nth number of levels deep I think I need to do some kind of array_walk funuction but not surch how. Also to make things just a little harder the machine it sists on runs PHP4 and I know it needs upgrading but it cant at the min so I need a php 4 solution ideally. How should I go about doing this?
Try the left/right tree method for storing hierarchical information in a database.
http://blogs.sitepoint.com/hierarchical-data-database/
This is what I do in my website, where I have multi-level LIs that need to open at 1:6 and have children 2:3,4:5 where the first number is the 'left' and the second is the 'right'. I have about 5 levels deep at the moment, but you could have many more. It's just a matter of developing an interface for setting the correct left/right values based on the position you add it to.
You just have to add a 'lft' and 'rgt' column to your table (as explained in that article).
First create a tree structure and insert your categories into the tree using id and parent_id. Then try Depth-first_search using either a list of references to arrays to be processed or recursion.
function printRecList($tree){
// exit condition
if (is_string($tree))
echo "<li>$tree</li>";
echo "<ul>";
foreach ($tree as $subtree)
printRecList($subtree); // recursion step
echo "</ul>";
}
The way your database is structured, you cannot do that with a single mysql query and you should do it recursively. Something in line with:
function print_children ($id) {
$children = query("SELECT * FROM `table` WHERE `parentId` = " . (int)$id);
if (!empty($children)) {
echo '<ul>';
foreach ($children as $child) {
echo '<li>' . $child['name'];
print_children($child['id']);
echo '</li>';
}
echo '</ul>';
}
}
print_children(0);
Replace query with something that gets results for your database query.
function writelevel($id, $txt, $children) {
if (isset($txt[$id]))
echo "<li id=\"$id\">".$txt[$id];
if (isset($children[$id])) {
echo "<ul>";
foreach ($children[$id] as $child)
writelevel($child, $txt, $children);
echo "</ul>";
}
if (isset($txt[$id]))
echo "</li>";
}
//Assuming your query is done and the result is in $qry
$txt=array();
$children=array();
//Fetch and structure data
while (true) {
//Fetch next row
$row=mysql_fetch_row($qry);
if (!$row) break;
//Store text
$txt[$row[0]]=$row[2];
//Store child relationships
if (!isset($children[$row[1]])) $children[$row[1]]=array();
$children[$row[1]]=$row[0];
}
//Writeout
writelevel(0);

Categories