0

Can someone please help me with this recursive function! It's messing up the incrementing of $x. I don't know what's wrong and I've been looking at it for so long now.

function list_dir($handle, $path) {
	// Loop over the directory and don\"t display certain files
	global $x;
	$x = 0;
	echo "<ul>";
	//running the while loop
	while (false !== ($file = readdir($handle))) {
		$extension = strtolower(substr(strrchr($file, '.'), 1)); 
		$dir =$path.'/'.$file;
		global $file_path;
		$file_path[$x] = $path;
		if(is_dir($dir) && $file != '.' && $file !='..' ) {
			$handle = opendir($dir) or die("unable to open file $file");
			echo "<li><b>$file</b></li>";
			list_dir($handle, $dir);
		}
		
		elseif($extension == "zip") {
			unlink($file);
		}
		
		elseif($extension == "mp3" || $extension == "mpa" && $file != '.' && $file !='..') {
			echo "<li><input type = \"checkbox\" name = \"file$x\" value = \"$file\" /><input type = \"hidden\" name = \"file".$x."_path\" value = 				\"".$file_path[$x]."\" /><a href=\"".$file_path[$x]."/$file\">$file</a></li>";
		}
		$x++;
	}

    echo "</ul>";
}
4
Contributors
15
Replies
16
Views
7 Years
Discussion Span
Last Post by baudday
0

I don't think there is a need to use $x. In general it is not a good idea to use globals in recursive functions. I have no possibility to test my code, but you could try this:

function list_dir($handle, $path, $x = 0) {
	// Loop over the directory and don\"t display certain files
	echo "<ul>";
	//running the while loop
	while (false !== ($file = readdir($handle))) {
		$extension = strtolower(substr(strrchr($file, '.'), 1)); 
		$dir =$path.'/'.$file;
		if(is_dir($dir) && $file != '.' && $file !='..' ) {
			$handle = opendir($dir) or die("unable to open file $file");
			echo "<li><b>$file</b></li>";
			$x = list_dir($handle, $dir, $x);
		}
 
		elseif($extension == "zip") {
			unlink($file);
		}
 
		elseif($extension == "mp3" || $extension == "mpa" && $file != '.' && $file !='..') {
			echo "<li><input type = \"checkbox\" name = \"file$x\" value = \"$file\" /><input type = \"hidden\" name = \"file".$x."_path\" value = 				\"".$path."\" /><a href=\"".$path."/$file\">$file</a></li>";
		}
		$x++;
	}
    echo "</ul>";
  return $x;
}

Edited by pritaeas: n/a

0

I am not sure what the point of $x is in that function besides being a counter. But this should solve your recursion issue.

<?php 

//Path to starting point
$path = '/your/path/goes/here';

//Create a recursive directory iterator
$iterator = new RecursiveDirectoryIterator($path);

echo "<ul>\n";
$x=0;

//Foreach iteration do something.
foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST) as $file)
{
	
	$extension = strtolower(end(explode('.',$file->getBasename())));
	
	if( $file->isDir() )
	{
		echo "<li><b>{$file->getBasename()}</b></li>\n";

	}
	else if( $file->isFile() && $extension == 'zip' )
	{
		//unlink($file->getPathname());
	}
	else if( $file->isFile() && ($extension == 'mp3' || $extension == 'mpa') )
	{
		echo "<li>
		      <input type = \"checkbox\" name = \"file$x\" value = \"{$file->getBasename()}\" />
		      <input type = \"hidden\" name = \"file".$x."_path\" value = \"{$file->getPathname()}\" />
		      <a href=\"{$file->getPathname()}\">{$file->getBasename()}</a>
		      </li>\n";
	}
	++$x;
}
echo "</ul>";

It appears $x is just being used so there is a unique number to put into the checkboxes. However with php if you are using this to build a form that you can select music files to delete or move or whatever, using a checkbox name of `anything[]` will create a php array of checkbox values on submit.

Then your checkbox value can be the actual path to the file including the filename. No need to have the hidden input then.

0

Awesome! Thanks for the help. That wasn't the exact solution, but it helped tremendously and pointed out a fatal flaw in my code. Every time list_dir was called it would reset $x to 0. So I defined $x outside the function, and passed it in as a variable. My code for that portion now looks like this.

$x = 0;
function list_dir($handle, $path,$x) {
	// Loop over the directory and don\"t display certain files
	echo "<ul>";
	//running the while loop
	while (false !== ($file = readdir($handle))) {
		$extension = strtolower(substr(strrchr($file, '.'), 1)); 
		$dir =$path.'/'.$file;
		global $file_path;
		$file_path[$x] = $path;
		if(is_dir($dir) && $file != '.' && $file !='..' ) {
			$handle = opendir($dir) or die("unable to open file $file");
			echo "<li><b>$file</b></li>";
			list_dir($handle, $dir,$x);
		}
		
		elseif($extension == "zip") {
			unlink($file);
		}
		
		elseif($extension == "mp3" || $extension == "mpa" && $file != '.' && $file !='..') {
			echo "<li><input type = \"checkbox\" name = \"file$x\" value = \"$file\" /><input type = \"hidden\" name = \"file".$x."_path\" value = 				\"".$file_path[$x]."\" /><a href=\"".$file_path[$x]."/$file\">$file</a></li>";
		}
		$x++;
	}

    echo "</ul>";
    return $x;
}
0

I was writing my reply as you were adding your last reply. Thank you. I will try this simpler method out. I did not know it automatically saved them in an array.

0

I'm trying mschroeder's method, and it's coming up with this error for each list item.

Strict Standards: Only variables should be passed by reference in /opt/lampp/htdocs/Music/index.php on line 97

Edited by baudday: n/a

0

Also, it is no longer indenting the filenames as appropriate. For instance Dir, subdir indented from that, filenames indented from that.

0

post what is on line 97 of your file. There is nothing in my code that is passed by reference.

The indentation will be a little more tricky but i'll see what i can do.

0

This would be line 97

$extension = strtolower(end(explode('.',$file->getBasename())));

I suppressed the error for now. And thanks, I really appreciate the help.

0

If at all possible, could you help me remove . and .. from the list of files shown? Thought I knew how, but I couldn't figure it out.

0

change that line to:

$parts = explode('.',$file->getBasename());
$extension = strtolower(end($parts));

apparently explode returns its value by reference.

Are . and .. showing? In my quick testing they didn't show up at all.

Edited by mschroeder: n/a

0

Yeah they're showing up several times actually scattered throughout the files.

0

I've now tested it on both linux (centos) and windows (xp) and both php 5.2.10 and php 5.3.0 and don't see the dot directories showing up.

<?php 
error_reporting(E_ALL | E_STRICT);

$path = '/path/to/file';

$iterator = new RecursiveDirectoryIterator($path);
$recurse = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
echo "<ul>\n";
$x=0;
foreach ( $recurse as $file)
{
	$parts = explode('.',$file->getBasename());
	$extension = strtolower(end($parts));
	
	if( $file->isDir() && !$recurse->isDot() )
	{
		echo "<li><b>{$file->getBasename()}</b></li>\n";
		
	}
	else if( $file->isFile() && $extension == 'zip' )
	{
		//unlink($file->getPathname());
	}
	else if( $file->isFile() && ($extension == 'mp3' || $extension == 'mpa') )
	{
		echo "<li>
		      <input type = \"checkbox\" name = \"file$x\" value = \"{$file->getBasename()}\" />
		      <input type = \"hidden\" name = \"file".$x."_path\" value = \"{$file->getPathname()}\" />
		      <a href=\"{$file->getPathname()}\">{$file->getBasename()}</a>
		      </li>\n";
	}
	++$x;
}
echo "</ul>";
0
$op = "<select name='opts' id='opts'>";
$dir = new DirectoryIterator( '/www/test/' );
foreach($dir as $file ){
  if(!$file->isDot() && !$file->isDir() && preg_match("/.mp3$/",$file->getFilename())) {
    $op .= "<option value='{$file->getFilename()}'>{$file->getFilename()}</option>";
  }
}
$op .= "<select>";
echo $op;

The above should print out all mp3 files to a dropdown. If you want to include other extensions, just change the regex in the preg_match parameter. 9 lines - should be nice. Cannibalize to your needs (ul list, etc).

Edited by diafol: doh!

0

So that solved some of the dots. The problem comes in when I get to a 3rd/4th level directory, Music->Artist->Album->Disc1 for instance. Then the dots start showing up again.

0

OOPS! Forgot to change one small part to what mschroeder suggested. The dots are gone. Any ideas on the indentation?

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.