Page 1 of 1

recursive file search

Posted: Mon Aug 15, 2005 4:58 am
by bladecatcher
G'day,
I'm trying to search for a file and return the path. Originally I thought I could find a simple example but I googled till I was gogled 8-0 without success, so I pieced together the following from another script. Yep, of coarse it doesn't work.

Where I echo "Inside Path:" the path is there and correct. However it doesn't get returned to the addPath function. Why???? Aaarrrrggghhhhhhhh.

Code: Select all

<?php
function addpath($docroot, $file_to_find){
	echo $docroot . "<br/>";
	$path = search($file_to_find, $docroot);
	echo "AddPath: " . $path . "<br/>";;
}

function search($target, $dir){
	if(is_dir($dir)){
		$dir2 = opendir($dir);
		while(false !== ($file = readdir($dir2))){
			if($file !="." && $file != ".."){
				if(is_file($dir."/".$file)){
					if(preg_match("/$target/i", $file)){
						echo "Inside Path: " . $dir . "<br/>";
						return $dir;
					}
				}else if(is_dir($dir."/".$file)){
					search($target,$dir."/".$file);
				}
			}
		}
		closedir($dir2);
	}
}
?>
Also any other newbie stupidities pointed out would be good.
Thanking you in anticipation,
blade

Posted: Mon Aug 15, 2005 7:07 am
by feyd
the find isn't recorded when you recurse from within your function. Also, when you do find the file, your function doesn't close the directory handle it has at that time. There's no failure return either, which would help in closing and returning the recursion. $target should be run through preg_quote() as well.

Posted: Mon Aug 15, 2005 7:52 am
by bladecatcher
Thank you for your reply.
Apologies but I don't understand.

When you say "the find isn't recorded when you recurse from within your function"
Does that mean because I'm calling 'search' from with 'search' the 'return' is lost?

"doesn't close the directory handle"
hmmm, yes I see, but ...

OK, could I ask for an example or pointer to how I might solve these?


The 'preg_quote()' I hope will become obvious when I read the manual.

Thank you again,
bladecatcher

Posted: Mon Aug 15, 2005 7:56 am
by feyd
bladecatcher wrote:When you say "the find isn't recorded when you recurse from within your function"
Does that mean because I'm calling 'search' from with 'search' the 'return' is lost?
yes.
bladecatcher wrote:"doesn't close the directory handle"
hmmm, yes I see, but ...

OK, could I ask for an example or pointer to how I might solve these?
You're very close at this point. Once you get the return value passing back, you'll probably figure out when you should close the directory handle.

bladecatcher wrote:The 'preg_quote()' I hope will become obvious when I read the manual.
it's a function that will escape all regular expression special characters

Posted: Tue Aug 16, 2005 3:04 am
by bladecatcher
Sorry, I've played a bit more but still coming to the same dead end.

When you say "Yes" to "calling 'search' from with 'search' the 'return' is lost", how is it lost?

and ... "it's a function that will escape all regular expression special characters" I don't think I need to as I'll be using the 'return' from 'addpath' to retrieve the file. Correct?

I've tried the following including the commented version but neither of which work, but as I think you guessed I'd really like to solve this however I'm at a dead end can you piont me down the path?

Code: Select all

<?php
function addpath($docroot, $file_to_find){
	echo $docroot . "<br/>";
	$path = search($file_to_find, $docroot);
	echo "AddPath: " . $path . "<br/>";;
}

function search($target, $dir){
	if(is_dir($dir)){
		$dir2 = opendir($dir);
		while(false !== ($file = readdir($dir2))){
			if($file !="." && $file != ".."){
				if(is_file($dir."/".$file)){
					if(preg_match("/$target/i", $file)){
						closedir($dir2);
						$dir = preg_quote($dir);
						echo "fullPath: " . $dir . "<br/>";
						//$fullPath = $dir;
						return $dir;
					}
				}else if(is_dir($dir."/".$file)){
					search($target,$dir."/".$file);
				}
			}
		}
		//closedir($dir2);
		//return $fullPath;
	}
}
?>
Again, thanking you in anticipation,
bladecatcher

Posted: Tue Aug 16, 2005 5:34 am
by jmut
haven't really looked into your function
here is one I am using....at least will help you see where you have problem.

Code: Select all

function scanDirectory($dir) {
        $subDirs = array();
        $dirFiles = array();
        if ($handle = @opendir($dir)) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != ".." ) {
                    if (is_dir($dir."/".$file)) {
                         $subDirs[] = $dir."/".$file;
                    } elseif (is_file($dir."/".$file)) {
                        $dirFiles[] = $dir."/".$file;
                    } else {
                            ///neither file, nor directory >>> not interested.
                    }
                }
            }
            closedir($handle);
            foreach($dirFiles as $file) {
                    //do something on each file....
            }
            if (count($subDirs) > 0) {
                foreach ($subDirs as $subDir) {
                    $this->scanDirectory($subDir);
                }
            }
        } else {
            // if inaccessible do something else
        }

    }

Posted: Tue Aug 16, 2005 7:07 am
by bladecatcher
Thank you Jmut,
that works well, but I really would like to find out what is wrong with my code. I'll keep yours just incase.

Thanks again,
bladecatcher

Posted: Tue Aug 16, 2005 7:46 am
by feyd
this is the problem "yes" was about:

Code: Select all

}else if(is_dir($dir."/".$file)){
                    search($target,$dir."/".$file);
                }
search() here may return something, but you completely ignore what it found, if anything. (You aren't storing the return value from that call.)

You need preg_quote() for here:

Code: Select all

if(preg_match("/$target/i", $file)){
specifically, $target must be run through preg_quote() ... unless you're expecting regular expressions to be passed in, I kinda doubt that..

Posted: Wed Aug 17, 2005 7:28 pm
by bladecatcher
Thank you feyd,
I can't believe I was soooo stupid to have not seen that. I fear age is not being kind to my brain cells.
warm regards,
bladecatcher
(well i was, but no longer it seems)