PHP download large file randomly breaks

Last two days, I was trying to make a PHP page to support large file downloading. It’s supposed to be fairly easy because PHP sample code is everywhere.

	
if (file_exists($file) && is_file($file)) 
{
    set_time_limit(0);
    //write HTTP header
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: '.filesize($file));
    header('Content-Disposition: filename='.basename($file));
    $handle = fopen($file, 'rb');
    while (!feof($handle)) 
    {
        //limited to 256kb/s
        print(fread($handle, 256 * 1024));
        // flush the content to the browser
        flush();
        // sleep one second
        sleep(1);
        if(connection_status() != 0 || connection_aborted()) 
        {
            break;
        }
    }
    fclose($handle);
    exit;
}

However, a small issue causes a big trouble. For unknown reason, HTTP downloading interrupts and breaks randomly, and I couldn’t download the entire file. I checked the PHP code and changed the PHP.ini, but still couldn’t solve the problem. After hours and hours digging, I found this page, https://www.lacisoft.com/blog/2012/01/21/php-download-script-for-big-files/, which magically solves the issue and saves me heaps.

it is :  ob_end_clean();

Here is the final code:

	
if (file_exists($file) && is_file($file)) 
{
    set_time_limit(0);
    //write HTTP header
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: '.filesize($file));
    header('Content-Disposition: filename='.basename($file));
    //!!!very important!!!
    ob_end_clean();
    $handle = fopen($file, 'rb');
    while (!feof($handle)) 
    {
        //limited to 256kb/s
        print(fread($handle, 256 * 1024));
        // flush the content to the browser
        flush();
        // sleep one second
        sleep(1);
        if(connection_status() != 0 || connection_aborted()) 
        {
            break;
        }
    }
    fclose($handle);
    exit;
}

I read the PHP manual about this function, and guess it could be PHP out buffering overflow or underflow causes the  break issue. If you are facing the similar issue, I hope this can help you as well.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.