2013-10-08 36 views
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?我對更高效的實現敞開懷抱。

+0

什麼是最終目標?你是否只需要所有文件夾中的所有文件,或者具有完整文件夾結構的關聯嵌套數組? – SmokeyPHP

+0

我需要文件夾中的所有文件。這些文件返回我需要的數組 –

回答

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/'); 
+0

你對我誤解遞歸是正確的。謝謝你。有一件事,我不需要在遞歸上做array_merge。我只需要設置$ arr = parseFolder(),否則我會有重複的值 –

+0

只要你照顧。並且......在限制深度方面沒有太多用處,如果你這樣做,你應該拋出一個異常而不是默默地返回一個劣等的答案。 – Sylwester

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