0

我想要做的是递归遍历所有文件夹并从每个文件中收集一个 $arr ,我稍后将合并。用高级术语来说,这就是我正在做的事情:

function main(){
    $path = ....
    $arr = array();
    if(is_dir($path)){
       $arr = parseFolder($path, $arr);
    } else {
       $arr = parseFile($path);
    }
    print $arr;
}
function parseFile($path){
   ....
   return $arr
}

function parseFolder($path, $arr){
   $folder = opendir($path);
   while($item=readdir($folder)){
      if(is_dir($item)
          parseFolder($path . '/' . $item, $arr);
      else
          $arr = merge_array($arr, parseFile($path . '/' . $item);

   }
   return $arr
}

正如您所看到的,这会出现问题,因为我没有基本案例。因此,它最终会在 parseFolder 函数中多次返回 $arr。有没有办法知道我什么时候几乎完成了对所有文件/文件夹的迭代,所以我知道什么时候返回我的最终结果 $arr?我对更有效的实施持开放态度。

4

2 回答 2

1

您需要更换:

parseFolder($path . '/' . $item, $arr);

$arr = array_merge($arr, parseFolder($path . '/' . $item, $arr));

否则你所有的递归调用都将被丢弃。

另外,我认为您对递归没有完全掌握,因为您似乎认为,如果您return在递归深处的任何一点上,它都会一直中断到原始调用。这是不正确的。

递归函数的唯一注意事项是:

  1. 确保你不会无限递归,例如。在这种情况下,是指向父目录的符号链接。
  2. 足够深的递归可能会导致堆栈溢出并使程序崩溃。

对于#1,您可以简单地避免处理符号链接,或者同时涵盖两者,您可以实施深度限制。例如:

<?php
define('RECURSE_MAXDEPTH', 10);

function myRecurse($path, $depth=0) {
  $arr = array();
  $folder = opendir($path);
  while( $item = readdir($folder) ) {
    if( is_dir($item) ) {
      if( $depth < RECURSE_MAXDEPTH ) {
        $arr = array_merge($arr, myRecurse($path.'/'.$item, $depth+1));
      }
    } else {
      $arr = array_merge($arr, someFunction($item));
    }
  }
  return $arr;
}

$myArr = myRecurse('~sammitch/');
于 2013-10-08T17:17:06.810 回答
0

您的代码中有一些语法错误。缺少括号几个地方,您使用常量folder而不是变量$folder,我希望merge_array实际上是array_merge

您的解决方案似乎是两种方法的混合:

添加提供的参考的变异版本。

function parseFolder($path, &$arr)
{
    $folder = opendir($path);
    while($item=readdir($folder)) {
        // current and parent directory shouldn't be processed
        if( $item == '.' || $item == '..' )
            continue;
        elseif( is_dir($item) )
            parseFolder($path . '/' . $item, $arr);
        else
            $arr = array_merge($arr, parseFile($path . '/' . $item));
    }
    // the supplied array is updated with the result
}

使用更深层次递归的返回值并按值构建的版本。

function parseFolder($path)
{
    $arr = array();
    $folder = opendir($path);
    while($item=readdir($folder)) {
        // current and parent directory shouldn't be processed
        if( $item == '.' || $item == '..' ) 
            continue;
        elseif( is_dir($item) )
            $arr = array_merge($arr, parseFolder($path . '/' . $item));
        else
            $arr = array_merge($arr, parseFile($path . '/' . $item));
    }
    return $arr;
}
于 2013-10-08T19:55:31.437 回答