简体   繁体   中英

Download file via PHP script from FTP server to browser with Content-Length header without storing the file on the web server

I use this code to download a file to memory from ftp:

public static function getFtpFileContents($conn_id , $file)
{
    ob_start();
    $result = ftp_get($conn_id, "php://output", $file, FTP_BINARY);
    $data = ob_get_contents();
    ob_end_clean();
    if ($resul)
        return $data;
    return null;
}

How can I make it directly send the file to the user (browser) without saving to disk and without redirecting to the ftp server ?

Just remove the output buffering ( ob_start() and the others).

Use just this:

ftp_get($conn_id, "php://output", $file, FTP_BINARY);

Though if you want to add Content-Length header, you have to query file size first using ftp_size :

$conn_id = ftp_connect("ftp.example.com");
ftp_login($conn_id, "username", "password");
ftp_pasv($conn_id, true);

$file_path = "remote/path/file.zip";
$size = ftp_size($conn_id, $file_path);

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . basename($file_path));
header("Content-Length: $size"); 

ftp_get($conn_id, "php://output", $file_path, FTP_BINARY);

(add error handling)


For more broad background, see:
List and download clicked file from FTP

public static function getFtpFileContentsWithSize($conn_id , $file)
{
    ob_start();
    $result = ftp_get($conn_id, "php://output", $file, FTP_BINARY);
    $data = ob_get_contents();
    $datasize = ob_get_length( );
    ob_end_clean();
    if ($result)
        return array( 'data' => $data, 'size' => $datasize );
    return null;
}


            $mapfile = SUPERFTP::getFtpFileContentsWithSize($ftpconn, $curmap['filename']);
            ftp_close($ftpconn);
            if (!$mapfile)
            {
                $viewParams['OutContext'] = "Error. File not found." ;
            }

            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename='.$curmap['filename']);
            header('Content-Transfer-Encoding: binary');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length: ' . $mapfile['size']); 

            echo $mapfile['data'];
            exit( );

This code works. Thanks all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM