PHP Crawler - 为什么readdir在循环退出时到达空文件夹?

时间:2012-10-14 05:41:25

标签: php recursion while-loop web-crawler readdir

我将以下函数作为一个较大程序的一部分来抓取所提供路径的内容,并将它在父文件夹或任何子文件夹中找到的任何.htm或.html页面编入索引。我的爬虫功能(下面)是递归的,似乎工作正常,直到它进入一个不包含任何项目的子文件夹。

这似乎是一个常见的问题,通常通过构造while循环来解决,如下所示:

while ( false !== ($file = readdir($folder)) )

但这不起作用。获得输出的最后一行是“当前爬虫路径是......”,然后输出就停止了。我猜这个问题是空文件夹和readdir函数,但我不知道如何解决它。有人可以提出建议吗?

由于

function crawlFolders($path)
{
    $prevPath = $path;  // variable to keep track of the previous file path
    chdir($path);
    $folder = opendir($path);

    echo "The current crawler path is ".$path."<br>";

    while ( false !== ($file = readdir($folder)) ) // read current directory item, then advance pointer
    {   
        if ( is_file($file) )
        {   echo "File found!  The crawler is inspecting to see if it can be indexed<br>";
            if ( canIndex($path."/".$file) )
                indexPage($path."/".$file);
        }

        else if ( is_dir($file) ) 
        {
            //it's a folder, we must crawl
            if ( ($file != ".") && ($file != "..") )    //it's a folder, we must crawl
            {
                echo "$file is a folder<br><br>";
                crawlFolders($path."/".$file);
                chdir($prevPath); // change the working dir back to that of the calling fn

            }
        }   
    }
    closedir($folder);

}

在看了这个之后,我看不出为什么readdir导致了这个问题。我认为问题可能是我的crawlFolders函数本身没有展开,而是在它到达最深的空文件夹时结束。我错过了递归应该有效的方法吗?我的印象是,一旦while循环返回false,递归函数调用将退出,从而将我放到先前的crawlFolders函数中,该函数进行递归调用(即展开自身)。

每次crawlFolders退出时,是否需要返回一个值,以便调用函数知道自己在哪里恢复?

看起来似乎递归就是问题。我把一个文件放在空文件夹中,我的索引器工作,但功能仍然没有按我想要的那样放松。我知道这没有发生,因为起始路径中仍有两个文件没有被评估。

1 个答案:

答案 0 :(得分:1)

问题不在于递归,而是很可能是当前的工作目录。

您使用chdir()更改当前目录,然后使用$file更改当前目录,并为is_file()is_dir()提供相对文件名。执行从递归返回后,当前目录仍然是子目录,因此is_file($file)is_dir($file)将找不到文件。

您必须在进入递归之前保存当前目录,或者 - 更好 - 完全避免使用chdir()并使用完整路径:is_file($path . '/' . $file)