Jump to content

Problems downloading files over about 30Mb via PHP


Gideon-IT

Recommended Posts

I'm a newbie to PHP but I want to amend a website I run for a musician friend of mine so that when people purchase his albums (sold as ZIP files) they don't see the link to the actual file, but PHP generates a randomly named copy, then downloads it for them and then deletes the copy when complete.  All works well except the download.  With the large files the download goes to about 1/2 way through and then just stalls until it aborts. 

 

Here's the code...

 

<?php
$path = "../_downloads/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['file'];

if ($fd = fopen ($fullPath, "r")) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "zip":
        header("Content-type: application/zip"); // add here more headers for diff. extensions
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
        break;
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    }
    header("Content-length: $fsize");
    header("Cache-control: private"); //use this to open files directly
    stream_set_timeout($fd, 600);
    while(!feof($fd)) {
        $buffer = fgets($fd,8192);
        echo $buffer;
    }
}
$info = stream_get_meta_data($fd);
fclose ($fd);

if ($info['timed_out']) {
    echo 'Connection timed out!';
} else {
    echo 'Done';
}
    
exit;
// example: place this kind of link into the document where the file download is offered:
// <a href="download.php?file=some_file.pdf">Download here</a>

?>

 

The link to run it is below...

www.godfreyb.com/_scripts/download.php?file=cd12_vg.zip

 

I've tried the @readfile(); function and this does the same thing, get to about 60.5 Mb and stalls.  I even tried passthru('cat ' . $fullPath); to send the file and that doesn't send anything at all.

 

The site is hosted by FastHosts on a Windows 2008 server with PHP5 installed.

 

Directly linking to the ZIP file results in a perfect download everytime.

 

Can anyone suggest a way to get this working?  It's driving me nuts!

To avoid being a lazy arse I looked it up on Google!  I've added the following lines to the beginning of the script...

 

 

ini_set('max_execution_time', 1200);

ini_set('memory_limit','1024M');

 

And am re-testing.

Yup, or using set_time_limit.

 

Forgot to add, because you're on a Windows server this is the case. On Linux the max execution time doesn't include stream operations, which you had increased the time-out of. I suspect you wouldn't be getting this problem on Linux.

Adam,

 

Well thanks to your excellent suggestions we've moved forward somewhat.  Now I get 132Mb of my 156Mb download - but still not all of it!  The modified code is below.  Any other ideas?

 

 

<?php

 

 

ini_set('max_execution_time', 1200);

ini_set('memory_limit','256M');

set_time_limit(1200);

 

$path = "../_downloads/"; // change the path to fit your websites document structure

$fullPath = $path.$_GET['file'];

 

if ($fd = fopen ($fullPath, "r")) {

    $fsize = filesize($fullPath);

    $path_parts = pathinfo($fullPath);

    $ext = strtolower($path_parts["extension"]);

    switch ($ext) {

        case "zip":

        header("Content-type: application/zip"); // add here more headers for diff. extensions

        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download

        break;

        default;

        header("Content-type: application/octet-stream");

        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");

    }

    header("Content-length: $fsize");

    header("Cache-control: private"); //use this to open files directly

    stream_set_timeout($fd, 1200);

    ob_clean();

    flush();

    while(!feof($fd)) {

        $buffer = fgets($fd,1024);

        echo $buffer;

    }

}

$info = stream_get_meta_data($fd);

fclose ($fd);

 

if ($info['timed_out']) {

    echo 'Connection timed out!';

} else {

    echo 'Done';

}

 

   

exit;

// example: place this kind of link into the document where the file download is offered:

// <a href="download.php?file=some_file.pdf">Download here</a>

 

?>

 

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.