【问题标题】:Recursively crawl files and directories and return a multidimensional array递归爬取文件和目录并返回多维数组
【发布时间】:2015-01-05 10:14:09
【问题描述】:

所以我一直在尝试创建一个递归文件目录树列表函数。我有大部分,除了一些错误。例如由于代码而导致的目录名称重复以及它在树中的深度不够。

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

返回的数组和这个类似

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"
   ...
  }
}

基本上我想做的就是得到这样的东西

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

希望你能理解我的要求,只需要看看这里出了什么问题,以及如何获得正确的索引来放置$currentFile,因为它正在搜索$allFiles[$path][$currentFile],这不会是正确的。无论如何只需要一个好的递归函数来列出数组中的所有文件,目录是索引。

【问题讨论】:

  • @Jonathan - 是不是有点不同,因为它是针对远程服务器的。必须实现一些功能来查看远程目录项是子文件夹还是文件。 ftp_nlist 手册有一些例子php.net/manual/ru/function.ftp-nlist.php
  • '/path/to/root/' 在链接的答案中可以是一个流(例如 ftp),它不必位于任何特定的物理位置

标签: php arrays recursion multidimensional-array


【解决方案1】:

扩展我评论中链接的答案,您可以将DirectoryIteratorftp:// 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;
}

【讨论】:

  • 我需要扩展它以不使用 DirectoryIterator 因为有些人可能没有它,因为它被添加到 PHP5 中。有些人可能仍在使用旧版本,我不知道,但总有一个人。
  • php5 10 年前发布
【解决方案2】:

我认为“$allFiles”变量没有任何理由应该是静态的。

另外,您正在使用一个未在任何地方定义的 $currentPath 变量。你想用那个变量来达到什么目的?

试试这段代码(它可能仍然不完美,但应该给你足够的提示,告诉你如何进行真正的递归):

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

【讨论】:

  • 您如何识别远程文件夹(潜入)?据我了解, ftp_nlist 仅返回一个普通列表。
  • 我正在检查字符串中的 .如果它在其中,它是一个文件,否则它是一个文件夹。还有更多的测试,但现在只是试图修复我的递归。我会在我回到我的电脑时检查一下,感谢您的快速响应
  • 我依靠 OP 逻辑来决定它是文件还是文件夹。我并不是说它在所有情况下都有效(它没有),我只是重用该部分的 OP 代码(无论如何这不是问题的主要焦点)。
  • 我的重点是递归和返回值
  • 这很好用,只需要稍微调试一下,但几乎完美,所以这是我接受的答案。谢谢马克西姆
猜你喜欢
  • 2017-05-31
  • 2012-08-13
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多