EasyBB
EasyBB

Reputation: 6544

Recursively crawl files and directories and return a multidimensional array

So I've been trying to create a recursive file directory tree listing function. I have most of it except some bugs. Such as duplicate directory names because of the code as well as it is not going deep enough in the tree.

function ftpFileList($ftpConnection, $path="/") {
    static $allFiles = array();
    $contents = ftp_nlist($ftpConnection, $path);
    foreach($contents as $currentFile) {
        if($currentFile !== "." && $currentFile !== ".."){
          if( strpos($currentFile,".") === false || strpos($currentFile,"." === 0) ) {
            if(!$allFiles[$path][$currentFile]){
                 $allFiles[$path][$currentFile] = array();
            }
            ftpFileList($ftpConnection,$currentFile);
         }else{
             if($currentPath !== "." && $currentPath !== "..") $allFiles[$path][] = $currentFile;
         }
      } 
   }
   return $allFiles;
}

The returned array looks similar to this

array(3) {
  [""]=>
      array(4) {
       [0]=>
        string(9) ".ftpquota"
       [1]=>
        string(9) ".htaccess"
       ["kms"]=>
        array(0) {
        }
       ["public_html"]=>
        array(0) {
        }
       }
  ["kms"]=>
     array(6) {
      [0]=>
       string(16) "admin_config.php"
      [1]=>
       string(8) "css.json"
      [2]=>
       string(10) "pages.json"
      ["php_includes"]=>
       array(0) {
       }
     ["site"]=>
       array(0) {
       }
     ["templates"]=>
       array(0) {
       }
      }
 ["public_html"]=>
   array(20) {
   [0]=>
    string(9) ".htaccess"
   [1]=>
    string(7) "404.php"
   ...
  }
}

Basically what I want to do is get something like this

.htaccess
.ftpquota
 -public_html
  -folder2
   -folder3
     file.ext
  file2.ext
 -kms
  -folder4
   file3.ext
   -folder5
    -file4.ext
   file5.ext

Hopefully you can understand what I am asking, just need to see what is wrong here, and how to get the correct index to place the $currentFile in because of the fact that it's search for $allFiles[$path][$currentFile] which won't be correct. anyways just need a good recursive function to list all files in an array, directories are indexes.

Upvotes: 1

Views: 1009

Answers (2)

Jonathan
Jonathan

Reputation: 1564

Expanding on the answer linked in my comment, you can use DirectoryIterator in combination with the ftp:// stream wrapper

$fileData = fillArrayWithFileNodes( new DirectoryIterator( 'ftp://path/to/root' ) );

function fillArrayWithFileNodes( DirectoryIterator $dir )
{
  $data = array();
  foreach ( $dir as $node )
  {
    if ( $node->isDir() && !$node->isDot() )
    {
      $data[$node->getFilename()] = fillArrayWithFileNodes( new DirectoryIterator( $node->getPathname() ) );
    }
    else if ( $node->isFile() )
    {
      $data[] = $node->getFilename();
    }
  }
  return $data;
}

Upvotes: 1

Maxime
Maxime

Reputation: 388

I don't think there's any reason the "$allFiles" variable should be static.

Also, you're using a $currentPath variable that isn't defined anywhere. What were you trying to achieve with that variable?

Try this code instead (it probably still isn't perfect, but should give you enough hint on how to make real recursion):

function ftpFileList($ftpConnection, $path="/") {
    $files = array();
    $contents = ftp_nlist($ftpConnection, $path);
    foreach($contents as $currentFile) {
        if($currentFile !== "." && $currentFile !== ".."){
          if( strpos($currentFile,".") === false || strpos($currentFile,"." === 0) ) {
            $files[$path][$currentFile] = ftpFileList($ftpConnection, $path.$currentFile.'/');
         }else{
             if($currentPath !== "." && $currentPath !== "..")
                 $files[$path][] = $currentFile;
         }
      } 
   }
   return $files;
}

Upvotes: 2

Related Questions