I have found plenty of examples of recursive functions to list directory contents, but I'm trying to do something a bit different.

I want to recursively walk a directory tree looking for something (it could be anything, such as a file with a particular file date, but let's just say I want to find a file named "happy.hhh"...) - and the catch is I want to terminate the function when I find what I'm looking for. There is no need to query 900 files if the second file matches my test, right?

So I have got all this to work so far, but the problem is how to exit the entire function. "Break" only exists the current "For" or "Foreach" loop and if the function is several levels deep, it simply picks up searching one level up.

If I use "return", same thing occurs.

If I use "exit" or "die", it works perfect as long as I'm only querying a single root directory since it stops the whole script. But I'm calling this function from other code and it stops this other code....

Hopefully someone has done something like this and could share. I'm sure there is a simple solution....

Thanks.

    Show us the skeleton of the function you're using - use pseudo code if you have to. You can solve this and still keep it recursive, or you can even rewrite the function to use a stack, which is great fun if you've never done it, and of course you can break out of that any time you like.

      Another idea is to use an accumulator to put the value you want in when you find it. When the function is entered, check the value of the accumulator. If it's still null, keep searching. If it isn't, just return.

      An auxiliary function can hide this.

      function find(...)
      {
           $found=null;
           find_aux(..., $found);
           return $found;
      }
      function find_aux(...., &$found){
      if($found!==null) return;
      ......
      }
      
        Drakla;10880757 wrote:

        Show us the skeleton of the function you're using...

        Here is a function I picked up somewhere and modified a bit since the original post... In this example, the goal is to search a directory tree, looking for a file that is newer than 2 years old. If such a file is found, stop searching that particular directory and return TRUE. If the entire directory is searched and all files are older than 2 years, return FALSE.

        Ultimately, I would want to call this function from another set of code that is looping through an entire drive for example...

        <?php
        function scanDirectories($rootDir) {
        
        $testdate = strtotime("-2 years");
        $invisibleFileNames = array(".", "..", "Thumbs.db");
        $dirContent = scandir($rootDir);
        
        foreach($dirContent as $key => $content) {
            $path = $rootDir.'/'.$content;
            if(!in_array($content, $invisibleFileNames)) {
                if(is_file($path) && is_readable($path)) {
                    $f = filemtime($path);               
                    if ($f > $testdate) {
                      $ret = true;
                      break;                  
                    }
                }elseif(is_dir($path) && is_readable($path)) {
                    scanDirectories($path);
                }
            }
        } 
        
          return $ret; 
        } // end function
        
        $ret = false;
        $dir = "//server/share/subdirectory/xxx/";
        $g = scanDirectories($dir);
        
        ?>
        

          You weren't utilising the recursive call to itself - so look at this:

          function scanDirectories($rootDir) {
          
          $testdate = strtotime("-6 year");
          $invisibleFileNames = array(".", "..", "Thumbs.db");
          $dirContent = scandir($rootDir);
          
          foreach($dirContent as $key => $content)
          {
              $path = $rootDir.'/'.$content;
          
              if (!in_array($content, $invisibleFileNames))
          	{
                  if (is_file($path) && is_readable($path))
          		{
                      $f = filemtime($path);               
                      if ($f < $testdate)
          			{	echo "Found File: $path<br />";
          				return true;
                      }
                  }
          		elseif(is_dir($path) && is_readable($path) && scanDirectories($path))  // <-- if it's a readable path, and it returns true then I'll also return true, which will ripple back down the chain
          		{
                     return true;
                  }
              }
          }
          
            return false;
          } // end function
          
          //$ret = false;
          //$dir = "//server/share/subdirectory/xxx/";
          $dir = '.';
          $g = scanDirectories($dir);
          
          echo (int)$g;

          I changed the testing parameters and put in an echo of the file found as I wanted to see what really old files I had knocking around my php directory.

            Drakla;10880925 wrote:

            You weren't utilising the recursive call to itself - so look at this

            Thanks a ton.

              Write a Reply...