Heim  >  Fragen und Antworten  >  Hauptteil

Rekursive PHP-FTP-Verzeichnisliste

<p>Ich versuche eine rekursive Funktion zu erstellen, um alle Verzeichnisse und Unterverzeichnisse von einem FTP-Server in einem Array abzurufen. </p> <p>Ich habe viele Funktionen ausprobiert, die ich online gefunden habe. Für mich funktioniert folgendes am besten: </p> <pre class="brush:php;toolbar:false;">public function getAllSubDirFiles() { $dir = array("."); $a = count($dir); $i = 0; $tiefe = 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; }</pre> <p>Das Problem mit dieser Funktion besteht darin, dass sie nicht zulässt, dass Verzeichnisse „.“ haben.Jede Datei im Stammverzeichnis wird auch in ihrem Namen als Verzeichnis betrachtet. Also habe ich die Funktion optimiert und Folgendes erhalten: </p> <pre class="brush:php;toolbar:false;">public function getAllSubDirFiles($ip, $id, $pw) { $dir = array("."); $a = count($dir); $i = 0; $tiefe = 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; }</pre> <p>Das funktioniert gut, liefert aber die gewünschten Ergebnisse. Aber es ist zu langsam in der Anwendung. </p> <p>Ich habe auch versucht, <code>ftp_rawlist</code> zu verwenden, aber es hatte den gleichen Nachteil, dass es sehr langsam war. </p> <pre class="brush:php;toolbar:false;">public function getAllSubDirFiles() { $dir = array("."); $a = count($dir); $i = 0; $tiefe = 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]; } anders { $fileName = $fileName . ' ' $newdir[$key][$a]; } $a++; } if ($firstChar != 'd') { unset($newdir[$key]); } elseif (!in_array($fileName, $dir)) { $dir[] = $fileName; } } } $b = count($dir); } return $dir; } öffentliche Funktion getFtp_rawlist($dir) { $newArr = array(); $arr = ftp_rawlist($this->connectionId, $dir); foreach ($arr als $value) { $stringArr = explosion(" ", $value); $newArr[] = array_values(array_filter($stringArr)); } return $newArr; }</pre> <p>Dieses Problem beschäftigt mich seit einigen Tagen und ich werde immer verzweifelter. Wenn jemand Vorschläge hat, lassen Sie es mich bitte wissen</p>
P粉621033928P粉621033928394 Tage vor597

Antworte allen(2)Ich werde antworten

  • P粉903052556

    P粉9030525562023-08-25 17:19:00

    我构建了一个 OOP FTP 客户端库,可以帮助您解决此问题很多,仅使用此代码,您可以检索仅包含附加有用信息的目录列表,例如(chmod、上次修改时间、大小...)。

    代码:

    // Connection
    $connection = new FtpConnection("localhost", "foo", "12345");
    $connection->open();
            
    // FtpConfig
    $config = new FtpConfig($connection);
    $config->setPassive(true);
    
    $client = new FtpClient($connection);
    
    $allFolders =
        // directory, recursive, filter
        $client->listDirectoryDetails('/', true, FtpClient::DIR_TYPE); 
    
    // Do whatever you want with the folders
    

    Antwort
    0
  • P粉763662390

    P粉7636623902023-08-25 11:29:06

    如果您的服务器支持 MLSD 命令并且您有 PHP 7.2 或更高版本,则可以使用 ftp_mlsd 函数

    function ftp_mlsd_recursive($ftp_stream, $directory)
    {
        $result = [];
    
        $files = ftp_mlsd($ftp_stream, $directory);
        if ($files === false)
        {
            die("Cannot list $directory");
        }
    
        foreach ($files as $file)
        { 
            $name = $file["name"];
            $filepath = $directory . "/" . $name;
            if (($file["type"] == "cdir") || ($file["type"] == "pdir"))
            {
                // noop
            }
            else if ($file["type"] == "dir")
            {
                $result = array_merge($result, ftp_mlsd_recursive($ftp_stream, $filepath));
            }
            else
            {
                $result[] = $filepath;
            }
        } 
        return $result;
    }

    如果您没有 PHP 7.2,您可以尝试自行实现 MLSD 命令。首先,请参阅 ftp_rawlist 命令的用户注释:
    https://www.php.net/manual/en/ function.ftp-rawlist.php#101071


    如果您无法使用MLSD,那么您在判断条目是文件还是文件夹时尤其会遇到问题。虽然您可以使用 ftp_size 技巧,但调用 每个条目的 ftp_size 可能需要很长时间。

    但是,如果您只需要针对一个特定的 FTP 服务器进行工作,则可以使用 ftp_rawlist 以特定于平台的格式检索文件列表并对其进行解析。

    以下代码假定采用常见的 *nix 格式。

    function ftp_nlst_recursive($ftp_stream, $directory)
    {
        $result = [];
    
        $lines = ftp_rawlist($ftp_stream, $directory);
        if ($lines === false)
        {
            die("Cannot list $directory");
        }
    
        foreach ($lines as $line)
        {
            $tokens = preg_split("/\s+/", $line, 9);
            $name = $tokens[8];
            $type = $tokens[0][0];
            $filepath = $directory . "/" . $name;
    
            if ($type == 'd')
            {
                $result = array_merge($result, ftp_nlst_recursive($ftp_stream, $filepath));
            }
            else
            {
                $result[] = $filepath;
            }
        }
        return $result;
    }

    对于 DOS 格式,请参阅:使用 PHP 从 FTP 获取目录结构

    Antwort
    0
  • StornierenAntwort