Stream FTP download to output

后端 未结 6 1180
耶瑟儿~
耶瑟儿~ 2020-12-03 06:06

I am trying to stream/pipe a file to the user\'s browser through HTTP from FTP. That is, I am trying to print the contents of a file on an FTP server.

This is what

6条回答
  •  攒了一身酷
    2020-12-03 06:38

    I know this is old, but some may still think it's useful.

    I've tried your solution on a Windows environment, and it worked almost perfectly:

    $conn_id = ftp_connect($host);
    ftp_login($conn_id, $user, $pass) or die();
    
    $sockets = stream_socket_pair(STREAM_PF_INET, STREAM_SOCK_STREAM,
            STREAM_IPPROTO_IP) or die();
    
    stream_set_write_buffer($sockets[0], 0);
    stream_set_timeout($sockets[1], 0);
    
    set_time_limit(0);
    $status = ftp_nb_fget($conn_id, $sockets[0], $filename, FTP_BINARY);
    
    while ($status === FTP_MOREDATA) {
        echo stream_get_contents($sockets[1]);
        flush();
        $status = ftp_nb_continue($conn_id);
    }
    echo stream_get_contents($sockets[1]);
    flush();
    
    fclose($sockets[0]);
    fclose($sockets[1]);
    

    I used STREAM_PF_INET instead of STREAM_PF_UNIX because of Windows, and it worked flawlessly... until the last chunk, which was false for no apparent reason, and I couldn't understand why. So the output was missing the last part.

    So I decided to use another approach:

    $ctx = stream_context_create();
    stream_context_set_params($ctx, array('notification' =>
            function($code, $sev, $message, $msgcode, $bytes, $length) {
        switch ($code) {
            case STREAM_NOTIFY_CONNECT:
                // Connection estabilished
                break;
            case STREAM_NOTIFY_FILE_SIZE_IS:
                // Getting file size
                break;
            case STREAM_NOTIFY_PROGRESS:
                // Some bytes were transferred
                break;
            default: break;
        }
    }));
    @readfile("ftp://$user:$pass@$host/$filename", false, $ctx);
    

    This worked like a charm with PHP 5.4.5. The bad part is that you can't catch the transferred data, only the chunk size.

提交回复
热议问题