2016-03-30 103 views
1

我試圖做一個遞歸函數來獲取我的FTP服務器中的所有目錄和子目錄在一個數組中。PHP的FTP遞歸目錄列表

我嘗試了很多我在網上找到的功能。最適合我的是這一個:

public function getAllSubDirFiles() { 
    $dir = array("."); 
    $a = count($dir); 
    $i = 0; 
    $depth = 20; 
    $b = 0; 
    while (($a != $b) && ($i < $depth)) { 
     $i++; 
     $a = count($dir); 
     foreach ($dir as $d) { 
      $ftp_dir = $d . "/"; 
      $newdir = ftp_nlist($this->connectionId, $ftp_dir); 
      foreach ($newdir as $key => $x) { 

       if ((strpos($x, ".")) || (strpos($x, ".") === 0)) { 
        unset($newdir[$key]); 
       } elseif (!in_array($x, $dir)) { 
        $dir[] = $x; 
       } 
      } 
     } 
     $b = count($dir); 
    } 
    return $dir ; 

} 

該功能的問題是它不會允許目錄有一個「。」在它的名稱中,並且位於根目錄中的每個文件也將被視爲一個目錄。所以我調整了功能,得到了這個:

public function getAllSubDirFiles($ip, $id, $pw) { 
    $dir = array("."); 
    $a = count($dir); 
    $i = 0; 
    $depth = 20; 
    $b =0; 
    while (($a != $b) && ($i < $depth)) { 
     $i++; 
     $a = count($dir); 
     foreach ($dir as $d) { 
      $ftp_dir = $d . "/"; 
      $newdir = ftp_nlist($this->connectionId, $ftp_dir); 
      foreach ($newdir as $key => $x) { 
       if (!is_dir('ftp://'.$id.':'.$pw.'@'.$ip.'/'.$x)) { 
        unset($newdir[$key]); 
       } elseif (!in_array($x, $dir)) { 
        $dir[] = $x; 
       } 
      } 
     } 
     $b = count($dir); 
    } 
    return $dir ; 

} 

這工作相當不錯,但給出了我想要的結果。但速度太慢,無法使用。

我也嘗試過與ftp_rawlist一起工作,但它的速度非常慢。

public function getAllSubDirFiles() { 
    $dir = array("."); 
    $a = count($dir); 
    $i = 0; 
    $depth = 20; 
    $b = 0; 
    while (($a != $b) && ($i < $depth)) { 
     $i++; 
     $a = count($dir); 
     foreach ($dir as $d) { 
      $ftp_dir = $d . "/"; 
      $newdir = $this->getFtp_rawlist('/' . $ftp_dir); 
      foreach ($newdir as $key => $x) { 

       $firstChar = substr($newdir[$key][0], 0, 1); 

       $a = 8; 
        while ($a < count($newdir[$key])) { 

         if ($a == 8) { 
          $fileName = $ftp_dir . '/' . $newdir[$key][$a]; 
         } else { 
          $fileName = $fileName . ' ' . $newdir[$key][$a]; 
         } 
         $a++; 
        } 

       if ($firstChar != 'd') { 
        unset($newdir[$key]); 
       } elseif (!in_array($fileName, $dir)) { 

        $dir[] = $fileName; 
       } 
      } 
     } 
     $b = count($dir); 
    } 
    return $dir; 
} 

public function getFtp_rawlist($dir) { 

    $newArr = array(); 

    $arr = ftp_rawlist($this->connectionId, $dir); 

    foreach ($arr as $value) { 

     $stringArr = explode(" ", $value); 

     $newArr[] = array_values(array_filter($stringArr)); 
    } 
    return $newArr; 
} 

我一直在這個問題上停留了幾天,我越來越絕望。如果任何人有任何建議請告訴我

回答

0

您必須使用目錄列表命令來檢索有關文件系統條目的詳細信息,以便您可以檢測到條目是文件還是文件夾。

使用ftp_rawlist。這具有不確定語法的列表的缺點。但是,如果只連接到一臺服務器(或僅限一臺服務器類型),如果不是很大的問題。

我看到你已經使用ftp_rawlist。但是你的代碼是錯誤的。它不斷重複讀取同一個文件夾。

使用簡單的遞歸,如:

function ftp_list_files_recursive($ftp_stream, $path) 
{ 
    $lines = ftp_rawlist($ftp_stream, $path); 

    $result = array(); 

    foreach ($lines as $line) 
    { 
     $tokens = explode(" ", $line); 
     $name = $tokens[count($tokens) - 1]; 
     $type = $tokens[0][0]; 
     $filepath = $path . "/" . $name; 

     if ($type == 'd') 
     { 
      $result = array_merge($result, ftp_list_files_recursive($ftp_stream, $filepath)); 
     } 
     else 
     { 
      $result[] = $filepath; 
     } 
    } 
    return $result; 
} 
+0

我已經editted我的代碼,所以你可以看到我用它來得到我的** ftp_rawlist功能**。我用這個** $ newdir = $ this-> getFtp_rawlist('/'。$ ftp_dir); **調用這個函數,並且據我所知它使用的是相同的連接,但它必須每次調用這個函數時間有一個子目錄 –

+0

我已經嘗試過,並已慘敗。你知道一個簡單的例子嗎? –

+0

非常感謝!因爲它現在它不適合我,因爲我有很多與他們的空間的文件夾,但有一些擺弄我認爲我可以使它工作 –