PHP FTP recursive directory listing
P粉621033928
P粉621033928 2023-08-25 00:36:20
0
2
551

I'm trying to create a recursive function to get all directories and subdirectories from an ftp server in an array.

I tried a lot of features I found online. The one that works best for me is this:

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

The problem with this function is that it does not allow directories to have "."Every file located in the root directory will also be considered a directory in its name. So I tweaked the function and got this:

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

This works fine but gives the results I want. But it's too slow to use.

I also tried using ftp_rawlist but it had the same drawback of being very slow.

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

I have been troubled by this problem for the past few days, and I am getting more and more desperate. If anyone has any suggestions please let me know

P粉621033928
P粉621033928

reply all (2)
P粉903052556

I built an OOPFTP client librarythat can help you solve this problem a lot, using just this code you can retrieve a directory listing with just additional useful information like (chmod, last modification time, size...).

Code:

// 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
    P粉763662390

    If your server supports theMLSDcommand and you have PHP 7.2 or higher, you can use theftp_mlsdfunction:

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

    If you don't have PHP 7.2, you can try to implement theMLSDcommand yourself. First, see the user notes for theftp_rawlistcommand:
    https://www.php.net/manual/en/ function.ftp-rawlist.php#101071


    If you are unable to useMLSD, you will particularly have problems determining whether anentry is a file or a folder. While you can use theftp_sizetrick, callingftp_sizefor each entry can take a long time.

    However, if you only need to work against one specific FTP server, you can use

    ftp_rawlistto retrieve a list of files in a platform-specific format and parse it.

    The following code assumes common *nix format.

    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; }
    For DOS format, see:

    Get directory structure from FTP using PHP.

      Latest Downloads
      More>
      Web Effects
      Website Source Code
      Website Materials
      Front End Template
      About us Disclaimer Sitemap
      php.cn:Public welfare online PHP training,Help PHP learners grow quickly!