How to force file download with PHP

后端 未结 11 1543
被撕碎了的回忆
被撕碎了的回忆 2020-11-21 23:13

I want to require a file to be downloaded upon the user visiting a web page with PHP. I think it has something to do with file_get_contents, but am not sure how

相关标签:
11条回答
  • 2020-11-21 23:23
    header("Content-Type: application/octet-stream");
    header("Content-Transfer-Encoding: Binary");
    header("Content-disposition: attachment; filename=\"file.exe\""); 
    echo readfile($url);
    

    is correct

    or better one for exe type of files

    header("Location: $url");
    
    0 讨论(0)
  • 2020-11-21 23:23

    You can stream download too which will consume significantly less resource. example:

    $readableStream = fopen('test.zip', 'rb');
    $writableStream = fopen('php://output', 'wb');
    
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="test.zip"');
    stream_copy_to_stream($readableStream, $writableStream);
    ob_flush();
    flush();
    

    In the above example, I am downloading a test.zip (which was actually the android studio zip on my local machine). php://output is a write-only stream (generally used by echo or print). after that, you just need to set the required headers and call stream_copy_to_stream(source, destination). stream_copy_to_stream() method acts as a pipe which takes the input from the source stream (read stream) and pipes it to the destination stream (write stream) and it also avoid the issue of allowed memory exhausted so you can actually download files that are bigger than your PHP memory_limit.

    0 讨论(0)
  • 2020-11-21 23:25

    The answers above me works. But, I'd like to contribute a method on how to perform it using GET

    on your html/php page

    $File = 'some/dir/file.jpg';
    <a href="<?php echo '../sumdir/download.php?f='.$File; ?>" target="_blank">Download</a>
    

    and download.php contains

    $file = $_GET['f']; 
    
    header("Expires: 0");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    
    $ext = pathinfo($file, PATHINFO_EXTENSION);
    $basename = pathinfo($file, PATHINFO_BASENAME);
    
    header("Content-type: application/".$ext);
    header('Content-length: '.filesize($file));
    header("Content-Disposition: attachment; filename=\"$basename\"");
    ob_clean(); 
    flush();
    readfile($file);
    exit;
    

    this should work on any file types. this is not tested using POST, but it could work.

    0 讨论(0)
  • 2020-11-21 23:26

    The following code is a correct way of implementing a download service in php as explained in the following tutorial

    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename=\"$file_name\"");
    set_time_limit(0);
    $file = @fopen($filePath, "rb");
    while(!feof($file)) {
        print(@fread($file, 1024*8));
        ob_flush();
        flush();
    }
    
    0 讨论(0)
  • 2020-11-21 23:33

    A modification of the accepted answer above, which also detects the MIME type in runtime:

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    header('Content-Type: '.finfo_file($finfo, $path));
    
    $finfo = finfo_open(FILEINFO_MIME_ENCODING);
    header('Content-Transfer-Encoding: '.finfo_file($finfo, $path)); 
    
    header('Content-disposition: attachment; filename="'.basename($path).'"'); 
    readfile($path); // do the double-download-dance (dirty but worky)
    
    0 讨论(0)
提交回复
热议问题