PHP FTP recursive directory listing

前端 未结 3 488
轻奢々
轻奢々 2020-12-10 09:12

I\'m trying to make a recursive function to get all the directories and sub directories from my ftp server in an array.

I tried a lot of functions I\'ve found on the

3条回答
  •  眼角桃花
    2020-12-10 09:59

    If your server supports MLSD command and you have PHP 7.2 or newer, you can use 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 do not have PHP 7.2, you can try to implement the MLSD command on your own. For a start, see user comment of the ftp_rawlist command:
    https://www.php.net/manual/en/function.ftp-rawlist.php#101071


    If you cannot use MLSD, you will particularly have problems telling if an entry is a file or folder. While you can use the ftp_size trick, calling ftp_size for each entry can take ages.

    But if you need to work against one specific FTP server only, you can use ftp_rawlist to retrieve a file listing in a platform-specific format and parse that.

    The following code assumes a 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.

提交回复
热议问题