P粉9030525562023-08-25 17:19:00
I built an OOP FTP client library that 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粉7636623902023-08-25 11:29:06
If your server supports the MLSD
command and you have PHP 7.2 or higher, you can use the ftp_mlsd
function :
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 the MLSD
command yourself. First, see the user notes for the ftp_rawlist
command:
https://www.php.net/manual/en/ function.ftp-rawlist.php#101071
If you are unable to use MLSD
, you will particularly have problems determining whether an entry is a file or a folder . While you can use the ftp_size
trick, calling ftp_size for each entry can take a long time.
ftp_rawlist to retrieve a list of files in a platform-specific format and parse it.
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.