我正在尝试构建一个递归函数,但在某种程度上函数不会显示所有目录。我错过了什么?我知道我可以使用 for or while,但我想要 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;
}
}
> 我猜如果你查看 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)
。它的翻译是is_file("images/folder1/folder2")
的,因为$this->srcFolder
等于images/folder1
。因此,这始终返回false
,直到它刚好到达foreach
的末尾并退出。
如果你改为调用$srcFolder
(局部变量),那么每次它到达函数时,它都会有正确的值。在相同的情况下:它进入folder1
,就在browse()
函数的第二级内,$srcFolder == "images/folder1"
.它列出了该文件夹的每个元素,然后返回到 images
。现在该函数仍然有其初始值 $srcFolder
,即 "images"
。因此,在foreach
循环的第二次迭代中,现在$val
再次等于folder2
,因此它对此调用browse()
。再次在函数的第二级中,$srcFolder == "images/folder2"
.在递归中使用局部变量可确保函数的每次调用都具有所需的值。