2010-11-05 176 views
2

我試圖創建一個目錄中的所有文件(及其大小)的列表包括子目錄中的所有內容。遞歸掃描目錄和子目錄通過FTP與PHP

這些文件位於遠程服務器上。所以我的腳本通過FTP連接,然後使用ftp_chdir運行遞歸函數來遍歷每個目錄。

如果還有其他方法可以做到這一點,我樂於接受建議。

$flist = array(); 

function recursive_list_dir($conn_id, $dir, $parent = "false") { 
global $flist; 
ftp_chdir($conn_id, $dir) or die("Fudgeballs: ".$parent."/".$dir); 
$list = array(); 
$list = ftp_rawlist($conn_id, "."); 

if($parent != "false") { $dir = $parent."/".$dir; } 

for($x = 0; $x < count($list); $x++) { 
    $list_details = preg_split("/[\s]+/", $list[$x]); 
    $file = $list_details[3]; 
    $size = $list_details[2]; 

    if(!strstr($file, ".")) { // if there's no dot (.), then we assume it's a directory (is there a command similar to "is_dir" for FTP? that would be more fail proof?) 
    recursive_list_dir($conn_id, $file, $dir); 
    } 
    else { $flist[] = $dir."@".$file."@".$size; } 
} 
ftp_chdir($conn_id, ".."); 
} 

recursive_list_dir($conn_id, "."); 

該腳本工作得很好,但現在它不工作。 PHP返回一個錯誤ftp_chdir。唯一改變的是我們已經將更多文件添加到服務器。如果我在子目錄上運行該腳本,該腳本將起作用。但是,如果我運行它「。」它失敗。那麼這是否因爲文件和子目錄太多而失敗?

+0

我認爲你不能在遠程服務器上運行任何東西? (也沒有PHP腳本或如此) – thejh 2010-11-05 22:41:15

回答

2

我沒有測試過這一點,但這裏是我做到了,而回:

$hostname = 'write.your.server.here'; 
    $username = 'username'; 
    $password = 'password'; 
    $startdir = 'starting/directory'; // absolute path 
    $suffix = "gif,png,jpeg,pdf,php"; // suffixes to list 
    $files = array(); 
    $conn_id = ftp_connect($hostname); 
    $login = ftp_login($conn_id, $username, $password); 
    if (!$conn_id) { 
     echo 'Wrong server!'; 
     exit; 
    } else if (!$login) { 
     echo 'Wrong username/password!'; 
     exit; 
    } else { 

     $files = raw_list("$startdir"); 
    } 

    ftp_close($conn_id); 

    function raw_list($folder) { 
     global $conn_id; 
     global $suffix; 
     global $files; 
     $suffixes = explode(",", $suffix); 
     $list  = ftp_rawlist($conn_id, $folder); 
     $anzlist = count($list); 
     $i = 0; 
     while ($i < $anzlist) { 
      $split = preg_split("/[\s]+/", $list[$i], 9, PREG_SPLIT_NO_EMPTY); 
      $itemname = $split[8]; 
      $endung = strtolower(substr(strrchr($itemname ,"."),1)); 
      $path  = "$folder/$itemname"; 
      if (substr($list[$i],0,1) === "d" AND substr($itemname,0,1) != ".") { 
       raw_list($path); 
      } else if(substr($itemname,0,2) != "._" AND in_array($endung,$suffixes)) { 
       array_push($files, $path); 
      } 
      $i++; 
     } 
     return $files; 
    } 
+0

非常好的人!非常感謝你。我正在使用這個。 – Steven 2013-09-16 18:28:55

+0

雖然不適用於所有情況。 – Chilion 2015-01-06 09:02:47

0

你給它更多的投入在此之前,這是工作的實質,似乎我認爲它可能是那裏存在問題。嘗試將set_time_limit(300);放在頂部,這樣可以在超時前運行5分鐘,然後查看是否可以解決問題。

+0

PHP手冊說默認的時間限制是30秒。而且我服務器上的PHP的max_execution_time是120.當我的腳本過去運行時,完成需要一段時間 - 超過120秒。這怎麼可能? PHP時間是單個命令還是整個腳本?我試圖將其設置爲300秒,沒有任何改變。 – boogz 2010-11-05 23:38:48

0

全局變量在PHP中的使用並不是很好的做法。看到這一點:

function ftp_get_files_list($conn_id, $baseDir='.') { 
    $files = array(); 
    $dirs = array($baseDir); 
    while($dir = array_shift($dirs)) { 
     $list = ftp_rawlist($conn_id, $dir); 
     while($line = array_shift($list)) { 
      $col = preg_split("@\[email protected]", $line); 
      if (count($col) <= 2) continue; 
      $fname = implode(' ',array_slice($col,8)); // support filenames with spaces 
      $isDir =($col[0][0]=='d'); 
      if ($isDir) 
       array_push($dirs, $dir.'/'.$fname); 
      else 
       array_push($files, $dir.'/'.$fname); 
     } 
    } 
    return $files; 
} 
0

不使用全局變量,一個真正的遞歸解決方案:

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; 
} 

適用於使用一個共同的* nix風格的房源如FTP服務器:

-r--r--r-- 1 ftp ftp    13 Nov 09 2015 file.txt 
dr-xr-xr-x 1 ftp ftp    0 Nov 10 2015 folder 

不適用於名稱中有空格的文件。