2016-03-30 11 views
1

Ich versuche, eine rekursive Funktion zu machen, um alle Verzeichnisse und Unterverzeichnisse von meinem FTP-Server in einem Array zu bekommen.PHP FTP rekursive Verzeichnisliste

Ich habe viele Funktionen ausprobiert, die ich im Internet gefunden habe. Die eine, die für mich am besten funktioniert, ist diese:

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 ; 

} 

Das Problem mit dieser Funktion ist es gewohnt das Verzeichnis erlauben, einen „“ in seinem Namen und jede Datei, die sich im Stammverzeichnis befindet, wird ebenfalls als Verzeichnis betrachtet. Also habe ich die Funktion angepasst und habe folgendes bekommen:

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 ; 

} 

Das funktioniert ziemlich gut aber und gibt das Ergebnis, das ich will. aber es ist so langsam, dass es unbrauchbar ist.

Ich habe auch versucht, mit ftp_rawlist zu arbeiten, aber es hat den gleichen Nachteil, schrecklich langsam zu sein.

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

Ich habe dieses Problem in den letzten paar Tagen festgefahren und ich bin verzweifelt. Wenn jemand einen Vorschlag hat, lassen Sie es mich wissen

Antwort

0

Sie müssen einen Verzeichnislistenbefehl verwenden, der Details zu den Dateisystemeinträgen abruft, so dass Sie erkennen können, ob der Eintrag eine Datei oder ein Ordner ist.

Verwenden Sie ftp_rawlist. Dies hat den Nachteil, dass die Auflistung eine nicht definierte Syntax hat. Aber wenn Sie nur einen Server (oder nur einen Server) verbinden, ist das kein großes Problem.

Ich sehe Sie, dass Sie bereits ftp_rawlist verwenden. Aber dein Code ist einfach falsch. Es liest den gleichen Ordner immer wieder neu.

Verwenden Sie eine einfache Rekursion wie:

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

Ich habe meinen Code editierte, so dass Sie die Funktion i ** ** meinen ftp_rawlist bekommen verwenden sehen können. Ich rufe diese Funktion mit diesem $ $ newdir = $ this-> getFtp_rawlist ('/'. $ Ftp_dir); ** und soweit ich feststellen kann, verwendet es die gleiche Verbindung, aber es muss diese Funktion alle aufrufen mal da ist ein Unterverzeichnis –

+0

das habe ich schon ausprobiert und kläglich gescheitert .. kennst du ein einfaches Beispiel? –

+0

Vielen Dank! So wie es jetzt aussieht, funktioniert es nicht für mich, da ich viele Ordner mit Leerzeichen in ihnen habe, aber mit etwas Fiedeln denke ich, ich kann es funktionieren lassen –