Primoz Rome
Primoz Rome

Reputation: 11031

PHP force download - files larger then 100MB will download only few bites

After my hosting provider upgraded server (Debian) and PHP (from 5.2.6 to 5.3.2) I am having problems with my file download script on our website. Files smaller then 100MB will download fine, but file larger then 100MB will download only as 156 Bytes file ... Here is my download script:

class Download_Controller extends Website_Controller
{

    public function index()
    {
        if (isset($_GET['file'])) {
          $file     = $_GET['file'];
          $filORM   = ORM::factory('file')->where('filename', $file)->find();

          if ($filORM->loaded and $filORM->deleted=='N' and file_exists(APPPATH.'downloads/'.$file) ) {
            //we can serve file download
            $this->auto_render = false;

            $filORM->counter = $filORM->counter + 1;
            $filORM->save();

            $dl = ORM::factory('download');
            $dl->download_file_id = $filORM->id;
            $dl->created = time();
            $dl->country_id = $this->country->id;
            $dl->ip = $this->_getRealIpAddr();
            $dl->browser = Kohana::user_agent('browser');
            $dl->version = Kohana::user_agent('version');
            $dl->platform = Kohana::user_agent('platform');
            $dl->save();

            return download::force(APPPATH.'downloads/'.$file);
          }
          else {
            $this->download_error();
          }

        }
        else {
            //else here we load download center UI
            $this->section();
        }
    }   
}

I am using Kohana PHP framework. Version 2.3.x.

Upvotes: 0

Views: 1762

Answers (4)

Maerlyn
Maerlyn

Reputation: 34107

In the comments, you gave me example links, I tried one, and that 156-byte file I downloaded contained this:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 141637633 bytes) in /home/www-data/system/helpers/download.php on line 93

It's quite clear - PHP ran out of memory. I presume while upgrading they also changed the memory_limit in php.ini. Short-term solution is to change it back to it's original (higher) value.

For downloading large files, you should look into mod_xsendfile (also available for servers other than apache), that involves setting a special http header, and leaving the work to the webserver instead of php.

Upvotes: 2

Justin T.
Justin T.

Reputation: 3701

You could try to readfile(APPPATH.'downloads/'.$file) and then exit() directly without return, then you will not be bound to memory issues anymore

Upvotes: 0

Timur
Timur

Reputation: 6718

I don`t know what`s the code of download::force(), but I think that it loads entire file into memory and PHP stops executing with error like Allowed memory size is exhausted. You need to load and output your file by small chunks checking if client aborted connection.

Update

Your file contains Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 141637633 bytes) in /home/www-data/system/helpers/download.php on line 93. So, as I wrote, output it by small chunks.

Upvotes: 0

Narf
Narf

Reputation: 14752

If Kohana's download::force() works the same way as in probably any other framework - PHP simply cannot or isn't allowed to hold more than 100MB of data in memory.

Upvotes: 0

Related Questions