PHP readfile() and large files

后端 未结 7 813
逝去的感伤
逝去的感伤 2020-12-05 20:12

When using readfile() -- using PHP on Apache -- is the file immediately read into Apache\'s output buffer and the PHP script execution completed, or does the PHP script exec

相关标签:
7条回答
  • 2020-12-05 20:27

    downloading files thru php isnt very efficient, using a redirect is the way to go. If you dont want to expose the location of the file, or the file isnt in a public location then look into internal redirects, here is a post that talks about it a bit, Can I tell Apache to do an internal redirect from PHP?

    0 讨论(0)
  • 2020-12-05 20:32

    Under Apache, there is a nice elgant solution not involving php at all:

    Just place an .htaccess config file into the folder containing the files to be offered for download with the following contents:

    <Files *.*>
    ForceType applicaton/octet-stream
    </Files>
    

    This tells the Apache to offer all files in this folder (and all its subfolders) for download, instead of directly displaying them in the browser.

    0 讨论(0)
  • 2020-12-05 20:35

    Try using stream_copy_to_stream() instead. I find is has fewer problems than readfile().

    set_time_limit(0);
    $stdout = fopen('php://output', 'w');
    $bfname = basename($fname);
    
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$bfname\"");
    
    $filein = fopen($fname, 'r');
    stream_copy_to_stream($filein, $stdout);
    
    fclose($filein);
    fclose($stdout);
    
    0 讨论(0)
  • 2020-12-05 20:38

    a few things you can do (I am not reporting all the headers that you need to send that are probably the same ones that you currently have in your script):

    set_time_limit(0);  //as already mention
    readfile($filename);
    exit(0);
    

    or

    passthru('/bin/cat '.$filename);
    exit(0);
    

    or

    //When you enable mod_xsendfile in Apache
    header("X-Sendfile: $filename");
    

    or

    //mainly to use for remove files
    $handle = fopen($filename, "rb");
    echo stream_get_contents($handle);
    fclose($handle);
    

    or

    $handle = fopen($filename, "rb");
    while (!feof($handle)){
        //I would suggest to do some checking
        //to see if the user is still downloading or if they closed the connection
        echo fread($handle, 8192);
    }
    fclose($handle);
    
    0 讨论(0)
  • 2020-12-05 20:41

    You may still have PHP output buffering active while performing the readfile(). Check that with:

    if (ob_get_level()) ob_end_clean();
    

    or

    while (ob_get_level()) ob_end_clean();
    

    This way theonly remaining output Buffer should be apache's Output Buffer, see SendBufferSize for apache tweaks.

    EDIT

    You can also have a look at mod_xsendfile (an SO post on such usage, PHP + apache + x-sendfile), so that you simply tell the web server you have done the security check and that now he can deliver the file.

    0 讨论(0)
  • 2020-12-05 20:51

    See below url

    http://php.net/manual/en/function.readfile.php

    <?php
    $file = 'monkey.gif';
    
    if (file_exists($file)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
    }
    ?>
    
    0 讨论(0)
提交回复
热议问题