recursive file search

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
bladecatcher
Forum Commoner
Posts: 67
Joined: Sat Mar 12, 2005 12:50 am

recursive file search

Post 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
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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.
bladecatcher
Forum Commoner
Posts: 67
Joined: Sat Mar 12, 2005 12:50 am

Post 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
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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
bladecatcher
Forum Commoner
Posts: 67
Joined: Sat Mar 12, 2005 12:50 am

Post 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
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Post 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
        }

    }
bladecatcher
Forum Commoner
Posts: 67
Joined: Sat Mar 12, 2005 12:50 am

Post 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
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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..
bladecatcher
Forum Commoner
Posts: 67
Joined: Sat Mar 12, 2005 12:50 am

Post 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)
Post Reply