[plug] PHP / mySQL - recursive query problem

Ady Gould KiltOtter at bdu.org
Tue Mar 30 18:53:04 WST 2004


Ok everyone, you will be glad to know that I basically solved the problem
when at work today.

So you all have the code, I will post it below...

Now I have a few nice little problems to make the code more easily reused -
like how to fill a certain control, or display the list in the manner I have
for the solution, and so on... Oh the fun!

Here is the code... Commented as much as I have for my TAFE students.

Ady


--------------------- SAMPLE CALLS --------------------------
List all the locations, and their 'sub-locations' [location ID = null,
maxDepth = 2]
	echo displayLocations( "" , 2 );

List all the locations, and their 'sub-locations' [location ID = null, no
max depth]
	echo displayLocations( "" );

List all the locations within Western Australia [location ID = 2, max depth
1]
	echo displayLocations( 1, 1 );

--------------------- END SAMPLE CALLS --------------------------


------------------ CODE BELOW --------------------
// // // // // // // // // // // // // // // // // // // // // // // // //
// // // // // //
// Function:   displayLocations
//
// Arguments:  $fromWhere (optional) is the locationID that you want to
start the search from
//             $maxDepth (optional) is the maximum number of levels that
will be traversed
//
// Usage:      In the current form there are two options:
//                  echo displayLocations( );
//             which displays the whole tree of locations.
//                  echo displayLocations( 3 );
//             which displays the tree of locations that are under the
locationID 3.
//                  echo displayLocations( "", 2 );
//             which displays the tree of locations that are from the 1st
level 
//             and for a total of 2 levels (eg Country -> state only)
//
// Author:     Adrian Gould 
//
// Date:       20040330
//
// Notes:      I have to express my thanks to Perth Linux User's Group
members,
//             LiveJournal's PHP and mySQL communities and other people for
their
//             assistance whilst I was bashing my head against a brick wall.
//
// Purpose:    Takes a location and returns all the sub-locations found in
that location,
//             recursively exploring for further sub-locations until the end
of the trail 
//             is reached.
//
// Copyright:  C Adrian Gould - released under GPL - please keep this
copyright notice in place
//             and add your comments below, including modifications and
updates.
//
// Change Log: 
//             20040330 - Added limiting argument to signify how many levels
of the tree
//                        are to be displayed when the function is called.
//
//             20040330 - after a number of hours bashing head against desk
at home, the 
//                        solution was probably something like a bad upload
of some scripts.
//
//
// Define function, setting a default for $fromWhere to be a null string.
//
// // // // // // // // // // // // // // // // // // // // // // // // //
// // // // // // // // //
function displayLocations ( $fromWhere = "" , $maxDepth = -1 )
{

    // make sure that the connection string is globally available, so we 
	// can use it here in this function.
	// also maintains a single database connection and reduces
overheads.
	global $connStationeryQuery;
	
	// set $resultSet to <ul> if it is not set already.
	if (!isset($result)) 
	{ 
		$result="<ul>";
	}
	
	// if $fromWhere is null, 
	//    then find all top level locations
	// else
	//    find all sub-locations that are listed for the 'fromWhere'
location
	if ( $fromWhere =="" )
	{
		$query_rsLocations = "SELECT * FROM tblLocations WHERE
foundWhere IS NULL ORDER BY locationID ASC";
	}
	else
	{
		$query_rsLocations = "SELECT * FROM tblLocations WHERE
foundWhere = '$fromWhere' ORDER BY locationID ASC";
	} // end if $fromWhere...
	
	// retrieve the recordset, or die!
	$rsLocations = $connStationeryQuery -> Execute ( $query_rsLocations
) or die ( $connStationeryQuery -> ErrorMsg() );
	
	// set a 'foundLocation' flag to false (not found)
	$foundLocation = false;
	
	// Check to see if any records exist, 
	// and if maxDepth is greater than zero (for limited levels)(
	//     or if less than zero (for all levels)
	// (note: to get the code to work as if it was called using depth
limited and depth unlimited
	//        recursion, we need to use a flag that says if this is the
case then we can keep traversing
	//        until we have exhausted all the possible entries on the
table. In this case it is -1 for
	//        this to happen. Any positive value will give that number
of levels. Zero gives no results)
	// if any records are found...
	if ( ( $rsLocations-> RecordCount() > 0 ) and ( ( $maxDepth > 0 ) or
( $maxDepth <= -1 ) ) )
	{
		// while not the end of the record set
		while ( ! $rsLocations -> EOF )
		{
			// Set the $foundLocation flag true, so that we know
we have to check for
			// sub-locations of the locations just found
			$foundLocation = true;
			
			// set a temporary variable to the locationID field
			$locID = $rsLocations -> Fields ('locationID');
			
			// Create a list item with the location text, and
the location ID
			// the location ID is formatted so that thousands
have "," separating
			// each group of three digits
			$result .= "<li>[" . number_format($locID) . "] ".
$rsLocations -> Fields ( 'location' ) ;
			
			// Now add to the end of the result any
sub-locations
			// that are found using the locID as the "parent"
and call it with the $maxDepth
			// being reduced by one.
			$result .= displayLocations ( $locID , ( $maxDepth -
1 ) )."</li>";
			
			// retrieve the next record from the result set
			$rsLocations -> MoveNext ();
			
		} // end while $rsLocations...
	}
	else
	{
		// end the current unordered list
		$result .='</ul>';
		
	} //end if Recordcount > 0
	
	// end the unordered list
	$result .= "</ul>";
	
	// close the record set
	$rsLocations -> Close();
	
	// if a location was found then
	if ( $foundLocation ) 
	{
		// return the $result string back to the previous
displayLocation call
		return $result;
	}
	else
	{
		// otherwise return a blank - signifying that there are no
further sub-locations
		// in the tree.
		// note that this is a good spot to put a HREF link to the
details about the
		// location that you hare listing
		return "";
	} // if $foundLocation...		
	
} // end function displayLocations
------------------ END CODE ----------------------





More information about the plug mailing list