2010-11-05 7 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

ответ

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

+0

Не работает для каждой ситуации. – Chilion

0

Тот факт, что она работает, прежде чем вы дали ему больше входов, мне кажется, предположить, что это может быть проблема там. Попытайтесь положить set_time_limit(300); вверху, что позволит ему работать в течение 5 минут до тайминга и посмотреть, устраняет ли это проблему.

+0

В руководстве по PHP говорится, что ограничение по умолчанию составляет 30 секунд. И max_execution_time PHP на моем сервере - 120. Когда мой скрипт работал в прошлом, потребуется некоторое время, чтобы закончить - дольше 120 секунд. Как это возможно? Устанавливает ли PHP отдельные команды или весь скрипт? Я попытался установить его на 300 секунд, и ничего не изменилось. – boogz

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

Работа для 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 

Не будет работать для файлов с пространством в его имени.

Смежные вопросы