Page 1 of 2

recursive class method

Posted: Sat Sep 15, 2007 1:20 am
by s.dot

Code: Select all

public function findJpgs($dir)
{
	if (!is_dir($dir))
	{
		trigger_error('Cannot find directory: ' . $dir, E_USER_ERROR);
	}
	
	$handle = opendir($dir);
	while (false !== ($file = readdir($handle)))
	{
		if (is_dir($file))
		{
			$this->findJpgs($file);
		} else
		{
			if (preg_match('/^.+?\.jp[e]?g$/i', $file))
			{
				echo $file . "\n";
			}
		}
	}
}
Tried this on the command line and browser.. it causes CLI to error and exit, and causes apache to stop working.

I've dealt with recursive functions, and the above should work in a function (haven't tested). Is there anything special I have to do if it's in a method?

Posted: Sat Sep 15, 2007 1:46 am
by s.dot
Oh, it's causing an infinite loop.. somewhere.

My guess is $this->findJpgs($file) needs a relative path (ie. $dir . '/' . $file), but I've never had that problem with recursion functions.

Posted: Sat Sep 15, 2007 2:07 am
by s.dot
Okay, wow. . and .. were causing an infinite (or at least very long) loop. So I got rid of those.

Turns out my next problem is a php bug. is_dir() won't support directories on windows given with a relative path. I need to use the absolute path, which will be a bit of a tough to figure out.

Unless there is a function to get the path of a given file?

Posted: Sat Sep 15, 2007 6:38 am
by VladSun
Sorry, I've never tested any PHP code on Windows, but here is my suggestion: real_path()

Posted: Sat Sep 15, 2007 7:40 am
by volka
scottayy wrote:Turns out my next problem is a php bug.
I cannot reproduce a php bug there. Which one is it?

readdir() does not return the given path, only the name of the file
opendir('x/y/z') + readir() -> fileA.php instead of x/y/z/fileA.php

The function shouldn't call itself for . and .. in any given directory.

Posted: Sat Sep 15, 2007 7:49 am
by VladSun
volka wrote:The function shouldn't call itself for . and .. in any given directory.
One should exclude symlinks too. ;)


@scottayy: I'd use $maxDepth, $depth++/-- and exit on $depth > $maxDepth

Posted: Sat Sep 15, 2007 8:20 am
by volka
VladSun wrote:
volka wrote:The function shouldn't call itself for . and .. in any given directory.
One should exclude symlinks too. ;)
Seems to be a bit harder on a win32 system. At least php 5.2.3 reported is_link()==false for a ntfs junction.

Posted: Sat Sep 15, 2007 8:34 am
by VladSun
volka wrote:
VladSun wrote:
volka wrote:The function shouldn't call itself for . and .. in any given directory.
One should exclude symlinks too. ;)
Seems to be a bit harder on a win32 system. At least php 5.2.3 reported is_link()==false for a ntfs junction.
What about using filetype() instead of is_link(). Does it work on win32? Sorry, I can't test it.

Posted: Sat Sep 15, 2007 9:02 am
by volka
Simply "dir".

Code: Select all

print_r(array_diff(stat('a'), stat('b')));
where b has been created via

Code: Select all

linkd b a
only prints
Array
(
[8] => 1189864834
[9] => 1189864834
[10] => 1189864834
[atime] => 1189864834
[mtime] => 1189864834
[ctime] => 1189864834
)

Posted: Sat Sep 15, 2007 9:34 am
by VladSun
And what about using lstat()?

Posted: Sat Sep 15, 2007 9:39 am
by volka
all the same.

Posted: Sat Sep 15, 2007 9:45 am
by VladSun
Grrr... That's why I have this signature ;)

Posted: Sat Sep 15, 2007 9:52 am
by volka
The link itself isn't the problem, only the possibility of cycles.

Posted: Sat Sep 15, 2007 9:55 am
by VladSun
volka wrote:The link itself isn't the problem, only the possibility of cycles.
Yes, but this problem introduces the second one ;)

Hm ... I can think of two solutions:
1) the $maxDepth solution above ...
2) a list of already listed directories ...

PS: and of course:
3) their combination

Posted: Sat Sep 15, 2007 12:56 pm
by s.dot
volka wrote:The function shouldn't call itself for . and .. in any given directory.
Are you saying that it shouldn't follow . and .. if my coding tells it to? Because before I added the check to skip those directories, it definitely followed them and not only sent me into a very long loop, but crashed the web server and cli.

As for the bug, this one seems to be closest to what I was looking at last night.

I'm probably just going to finish developing this script on my ubuntu box. Trying to complete it on windows is making me really hack it up by using if (!is_file()) instead of is_dir().