2013-10-20 285 views
1

我想构建一个递归函数,但在某种方式函数不会显示所有的目录。我缺少什么?我知道我可以使用或一段时间,但我想foreach循环。下面是代码:用foreach循环递归

$GLOBALS['testmodus']=0; 
$o=new BrowseFolder(); 
$o->browse('../images/',1); 
ta($o); 
function ta($ausgabe) { 
    echo('<p class="ta">'.__LINE__.$ausgabe.'</p>'); 
} 


class BrowseFolder{ 
    private $srcFolder; 
    private $ifRecursiv=0; 
    private $excludeFileTypes=array('.','..'); 
    private $filesFound; 
    private $deleteFolderPath=0; 
    private $makeFolderPath; 

    public function browse($srcFolder,$ifRecursiv=0){ 
     ta($this->filesFound); 
     $this->srcFolder=$srcFolder; 
     $this->ifRecursiv=$ifRecursiv; 
     $this->filesFound=scandir($this->srcFolder); 
     $this->filesFound=$this->excludeArrayFromArray($this->filesFound,$this->excludeFileTypes); 
     echo "<ul>"; 
     foreach($this->filesFound as $val){ 
       if(is_file($this->srcFolder.$val)){ 
        echo "<li>"; 
        echo "$val"; 
        echo "</li>"; 
        }elseif(is_dir($this->srcFolder.$val) && $this->ifRecursiv==1){ 
         ta($this->srcFolder.$val); 
         echo "$val"; 
         $this->browse($this->srcFolder.$val.'/',$this->ifRecursiv); 

         } 
     } 
     echo "</ul>"; 
    } 

    private function excludeArrayFromArray($baseArray,$arrayToExclude){ //Exclude an array from another array,and arrange 
     $newArray=array_values(array_diff($baseArray,$arrayToExclude)); 
     return $newArray; 

    } 
} 
+2

您可以添加更多关于它不通过所有文件夹的方式吗?你有没有考虑过使用DirectoryIterator? http://php.net/manual/en/class.directoryiterator.php –

+1

@ Ronni Skansing - 可能需要递归版本:http://php.net/manual/en/class.recursivedireiteiterator。php – ChicagoRedSox

+0

@ChicagoRedSox +1;) –

回答

1

我要去猜,如果你看了Web服务器日志,你会看到这样的错误:

PHP Catchable fatal error: Object of class BrowseFolder could not be converted to string in <filename> on line <XX> 

BrowseFolder类没有__toString()方法,所以试图调用它的字符串上下文抛出一个致命错误(这条线:ta($o);

但是,这只是问题1. 问题2是这样的:

$this->srcFolder=$srcFolder; 

由于BrowseFolder类只有一个实例,因此您需要在该类上设置一个属性,然后尝试在递归中重用该实例。所以基本上它是在钻入第一个文件夹,然后因为$this->srcFolder就等于后来的那些孩子,所以没有尝试去更进一步。将$this->srcFolder的每个实例替换为$srcFolder。递归函数然后将深入到第一个,然后当它到达最后时,回到第一个调用browse(),然后继续到第二个,依此类推。

编辑 - 附加细节: 它不应被修改每个时间变量。它正在做的是取第一个文件夹images,然后在该类上设置该属性。它归入该文件夹的第一个孩子 - 称为folder1,然后再次将类属性设置为该孩子(即$this->srcFolder == "images/folder1")。它列出该文件夹中的文件,然后继续。由于该文件夹中没有更多文件或子目录,因此到达该迭代的末尾。然后它回到images文件夹。它转到foreach循环的下一次迭代,现在将$val设置为folder2。现在它尝试if(is_file($this->srcFolder.$val))else if (is_dir($this->srcFolder.$val)。由于$this->srcFolder等于images/folder1,所以翻译为is_file("images/folder1/folder2")。因此,这总是返回false,直到它刚刚到达foreach的末尾并退出。

如果您改为拨打$srcFolder(局部变量),那么每次到达函数时它都会有正确的值。在相同的情况下:它进入folder1,并在browse()函数的第二级$srcFolder == "images/folder1"内。它列出了该文件夹的每个元素,然后回到images。现在该函数的初始值仍为$srcFolder,即"images"。因此,在foreach循环的第二次迭代中,现在$val再次等于folder2,因此它在那上调用browse()。再次在函数的第二级,$srcFolder == "images/folder2"。在递归中使用局部变量可确保函数的每次调用都具有所需的值。

+0

谢谢,@ ChicagoRedSox。第一个问题是看到它。只有一个检查功能。第二个...嗯,我认为我的函数正在调试$ srcFolder类变量,每次改变路径。那么,为什么不工作? –

+0

说明太长了,不会发表评论:我会将它添加到答案中... – ChicagoRedSox

+0

我认为问题存在于此代码中:$ this-> srcFolder。$ val .I认为srcFolder。$ val尝试连接并然后解决$这。类似的东西:($ this - >)srcFolder。$ val。要么? @ChicagoRedSox –