Rumah  >  Soal Jawab  >  teks badan

Penyenaraian direktori rekursif PHP FTP

<p>Saya cuba mencipta fungsi rekursif untuk mendapatkan semua direktori dan subdirektori daripada pelayan ftp dalam tatasusunan. </p> <p>Saya mencuba banyak ciri yang saya temui dalam talian. Yang paling sesuai untuk saya ialah ini: </p> <pre class="brush:php;toolbar:false;">fungsi awam getAllSubDirFiles() { $dir = array("."); $a = count($dir); $i = 0; $depth = 20; $b = 0; manakala (($a != $b) && ($i < $depth)) { $i++; $a = count($dir); foreach ($dir sebagai $d) { $ftp_dir = $d . $newdir = ftp_nlist($this->connectionId, $ftp_dir); foreach ($newdir sebagai $key => $x) { jika ((strpos($x, ".")) || (strpos($x, ".") === 0)) { unset($newdir[$key]); } elseif (!in_array($x, $dir)) { $dir[] = $x; } } } $b = kiraan($dir); } pulangkan $dir; }</pre> <p>Masalah dengan fungsi ini ialah ia tidak membenarkan direktori mempunyai "."Setiap fail yang terletak dalam direktori akar juga akan dianggap sebagai direktori dalam namanya. Jadi saya tweak fungsi dan mendapat ini: </p> <pre class="brush:php;toolbar:false;">fungsi awam getAllSubDirFiles($ip, $id, $pw) { $dir = array("."); $a = count($dir); $i = 0; $depth = 20; $b =0; manakala (($a != $b) && ($i < $depth)) { $i++; $a = count($dir); foreach ($dir sebagai $d) { $ftp_dir = $d . $newdir = ftp_nlist($this->connectionId, $ftp_dir); foreach ($newdir sebagai $key => $x) { jika (!is_dir('ftp://'.$id.':'.$pw.'@'.$ip.'/'.$x)) { unset($newdir[$key]); } elseif (!in_array($x, $dir)) { $dir[] = $x; } } } $b = kiraan($dir); } pulangkan $dir; }</pre> <p>Ini berfungsi dengan baik tetapi memberikan hasil yang saya inginkan. Tetapi ia terlalu lambat untuk digunakan. </p> <p>Saya juga cuba menggunakan <code>ftp_rawlist</code> tetapi ia mempunyai kelemahan yang sama iaitu sangat lambat. </p> <pre class="brush:php;toolbar:false;">fungsi awam getAllSubDirFiles() { $dir = array("."); $a = count($dir); $i = 0; $depth = 20; $b = 0; manakala (($a != $b) && ($i < $depth)) { $i++; $a = count($dir); foreach ($dir sebagai $d) { $ftp_dir = $d . $newdir = $this->getFtp_rawlist('/' . $ftp_dir); foreach ($newdir sebagai $key => $x) { $firstChar = substr($newdir[$key][0], 0, 1); $a = 8; manakala ($a < count($newdir[$key])) { jika ($a == 8) { $fileName = $ftp_dir '/' . } lain { $fileName = $fileName . } $a++; } jika ($firstChar != 'd') { unset($newdir[$key]); } elseif (!in_array($fileName, $dir)) { $dir[] = $fileName; } } } $b = kiraan($dir); } pulangkan $dir; } fungsi awam getFtp_rawlist($dir) { $newArr = array(); $arr = ftp_rawlist($this->connectionId, $dir); foreach ($arr sebagai $value) { $stringArr = explode(" ", $value); $newArr[] = array_values(array_filter($stringArr)); } pulangkan $newArr; }</pre> <p>Saya telah bermasalah dengan masalah ini sejak beberapa hari lalu, dan saya semakin terdesak. Jika sesiapa mempunyai sebarang cadangan sila beritahu saya</p>
P粉621033928P粉621033928394 hari yang lalu598

membalas semua(2)saya akan balas

  • P粉903052556

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

    Saya membina OOP FTP client library yang boleh membantu anda menyelesaikan masalah ini dengan banyak, hanya menggunakan kod ini anda boleh mendapatkan senarai direktori dengan hanya maklumat berguna tambahan seperti (chmod, masa diubah suai terakhir, saiz... .).

    Kod:

    // 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
    

    balas
    0
  • P粉763662390

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

    Jika pelayan anda menyokong fungsi 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;
    }

    Jika anda tidak mempunyai PHP 7.2, anda boleh cuba melaksanakannya sendiri MLSD 命令。首先,请参阅 ftp_rawlist Nota pengguna untuk arahan:
    https://www.php.net/manual/en/ function.ftp-rawlist.php#101071


    Jika anda tidak mempunyai akses kepada MLSD, anda akan menghadapi masalah untuk mengetahui sama ada entri adalah fail atau folder MLSD,那么您在判断条目是文件还是文件夹时尤其会遇到问题。虽然您可以使用 ftp_size 技巧,但调用 每个条目的 ftp_size. Walaupun anda boleh menggunakan helah ftp_size, memanggil ftp_size setiap entri boleh mengambil masa yang lama.

    Walau bagaimanapun, jika anda hanya perlu bekerja dengan satu pelayan FTP tertentu, anda boleh menggunakan ftp_rawlist untuk mendapatkan semula senarai fail dalam format khusus platform dan menghuraikannya.

    Kod berikut menganggap format *nix biasa.

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

    Untuk format DOS, lihat: Dapatkan struktur direktori daripada FTP menggunakan PHP.

    balas
    0
  • Batalbalas