2012-10-14 50 views
1

我具有以下功能作爲更大程序的一部分,該程序可對所提供路徑的內容進行爬網,並對其在父文件夾或任何子文件夾中找到的任何.htm或.html頁面編制索引。我的爬蟲功能(下)是遞歸的,似乎工作得很好,直到它到達不包含項目的子文件夾。PHP Crawler - 爲什麼readdir while循環在到達空文件夾時退出?

這似乎是一個常見的問題,往往是通過構造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退出時,我是否需要返回一個值,以便調用函數知道自己恢復的位置?

它肯定看起來像遞歸是問題。我在空文件夾中放置了一個文件,並且我的索引器工作正常,但功能仍然沒有按照我的意願放鬆。我知道這不會發生,因爲在起始路徑中仍有兩個文件未被評估。

+0

您的代碼看起來是正確的,你可以確保您看到PHP錯誤,如果他們發生(error_reporting/display_errors)? – AndreKR

+0

不熟悉錯誤報告,但我打開了它,沒有看到任何顯示。我添加了一些更多的原始帖子...我開始認爲遞歸不能正常工作。 – PSUlion01

回答

1

問題不是遞歸,而是很可能是當前的工作目錄。

您使用chdir()更改當前目錄,然後使用$file更改當前目錄,您給出的相對文件名爲is_file()is_dir()。執行從遞歸返回後,當前目錄仍然是子目錄,因此is_file($file)is_dir($file)將找不到文件。

您必須進入遞歸或之前保存在當前目錄 - 更好 - 避免chdir()乾脆用完整路徑工作:is_file($path . '/' . $file)

+0

我看到你在說什麼,但是我沒有看到$ path正在被重新分配,因爲它進入了遞歸函數。我在程序中的其他地方分配了$ path值,並且在爬網時不重新分配它,我只是追加$ file變量。 因此...輸入函數path = $ path。當調用crawlFolders時,我傳遞:'crawlFolders($ path。「/」。$ file)'。不應該$ path與我們從遞歸調用返回時原來的一樣,因爲我將$ file附加到路徑字符串中,而不是重新分配'$ path = $ path。「/」。$ file;' ? – PSUlion01

+0

我正在討論改變當前工作目錄的chdir($ path)*,它是全局的(在返回時不會恢復),當你將相關文件名傳遞給'is_file($文件)'。 – AndreKR

+0

我的印象是,由於我通過值而不是通過引用傳遞'$ path',因此每次遞歸函數調用都會創建一個新的'$ path'副本。因此,我認爲這個副本會在每層遞歸展開時被丟棄。 這裏的問題是,雖然'$ path'是通過值傳遞的,但它被視爲一個全局對象,因爲'crawlFolders()'仍然只被看作一個函數,而不管由於遞歸調用而存在多少個實例? 希望我有道理......謝謝! – PSUlion01