Query::Arrays - Correct Usage

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
randomblink
Forum Commoner
Posts: 51
Joined: Wed Jan 28, 2004 11:27 am
Location: Tulsa, Oklahoma, just this side of hell...
Contact:

Query::Arrays - Correct Usage

Post by randomblink »

Alright...
I am TRYING to build a Class where part of it is used to traverse a Directory. I have been using opendir and readdir to grab the files...

However, I WANT to skim through a directory...
As I go THROUGH the directory...
I want to add File / Folder names to an Array...
As I hit a Folder, I ALSO want to skim through it and do the same...
Kinda a repeat...

I am as lost as they get...
I THOUGHT I had it figured out...
Here are some pieces of the class...

Code: Select all

function _FolderListing( $path ) 
	{
		if ( $handle = opendir( $path ) ) 
		{
			$folders = explode( "/", $path );
			$Number = count( $folders ) - 2;
			$folder = $folders[$Number];
		
			while ( False !== ( $file = readdir( $handle ) ) ) 
			{
				$ItemNumber = count( $this->Folder ) - 1;
				if ( $file != "." && $file != ".." ) 
				{
					$this->Folder[$folder] = array	
					(
						'itemID' => ,
						'itemName' => $file,
						'itemPath' => $path,
						'itemFULLPath' => $path . $file,
						'itemType' => ( is_file( $path . $file ) ) ? "File":"Folder"
					);
					if( $this->Folder[$folder]['itemType'] == "Folder" ) 
					{
						$newPath = $path . $file . "/";
						$this->_FolderListing( $newPath );
					}
				}
			}
			closedir( $handle );
		}
	}

	function TEST(  ) 
	{
		$this->_FolderListing( $this->_pathToPackage( 'coreSystem' ) );
		
		$test = $this->BreakDown( $this->Folder ); 

		Return $test;
	}

	function BreakDown( $arr ) 
	{
		$temp .= "<table border="1">";
		$temp .= "<tr><td>key</td><td>val</td></tr>";
		foreach( $arr as $key=>$val ) 
		{
			if( is_array( $val ) ) 
			{
				$temp .= "<tr><td>$key</td<td>" . $this->BreakDown( $val ) . "</td><>tr>";
			}
			else 
			{
				$temp .= "<tr><td>$key</td><td>$val</td></tr>";
			}
		}
		$temp .= "</table>";
		Return $temp;
	}
If you can help with this, I would be greatly appreciative... I am just lost. It could be that I have never fully grasped Arrays. I understand the concept, but I have never had a real world explanation that made sense... Ah well...
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

What you really want is a TreeIterator ie a class (or classes) which will iterate through the contents of each node in a tree, right down to the end of each branch.

Tree "nodes" in the filesystem example are folders and node contents are files or folders (ie other nodes). An XML file also has a tree type structure: if you get the TreeIterator right it can be re-used in an XML parser or indeed with any kind of tree.

As you iterate through each node, you need some case logic to check if found items are nodes or not, and methods (or other classes) to process them appropriately.

Nodes could be added to a $nodes_list array as they are found. If you iterate through $nodes_list with:

Code: Select all

<?php
while(!is_null($item = array_shift($this->nodes_list)))
{
    // etc
}
?>
... this allows you to add found nodes to the array even as you iterate over it. Hence you get the desired recursive behaviour.

There's an obvious risk of infinite loops... It works with trees since each branch has a finite end. With a filesystem eg, eventually you run out of new folders to add to $nodes_list.

It might be best to aggregate other classes to deal with the actual item processing. With just the bare iteration bones in TreeIterator it can be re-used for any recursive tree operation.

The Observer pattern could be useful here.
Post Reply