0

I have written a module that creates a zip file in the /tmp and then downloads the zip file through browser i.e. it will be downloaded in the ~/Downloads directory by itself.

I don't want to use hook_file_download() because it executes everytime you try to download a file, but I want to be specific while downloading. The above code snippet is written in the same function that creates the zip file.

I have taken the help of davidwalsh blog to create the zip file.

I can create the zip file in /tmp directory, but how to download the zip file.

My code looks like this:

$fp = fopen($filesystem_filepath, 'rb');
header('Content-type: application/octet-stream');
header('Content-Length: '. filesize($filesystem_filepath));
fpassthru($fp);

At first I tried downloading simply using header() function and then after more googling I took the help of readfile($filesystem_filepath) instead of fpassthru($fp) but its not working.

1 Answer 1

3

You don't mention exactly what's not working, but at a guess it might be that the download works in all browsers except Internet Explorer?

IE is an annoyance when it comes to forcing downloads, you really have to go around the houses to get all versions to respect what you're trying to do.

Here's the code I use to force downloads, and it works cross browser (updated to address @MPD's comment below):

function force_file_download($path, $filename) {
  // Most of this is only necessary because of IE
  header("Cache-Control: public");
  header("Content-Type: application/octet-stream");
  header("Cache-Control: no-store, no-cache, must-revalidate");
  header("Cache-Control: post-check=0, pre-check=0");
  header("Content-Disposition: attachment; filename=\"$filename\";" );
  header("Content-Transfer-Encoding: binary");

  $fp = fopen($path, 'rb');
  fpassthru($fp);
  exit();
}

You'd use it in a page callback like this:

force_file_download($filesystem_filepath, 'file.zip');

That code works perfectly for me for any type of file, cross-browser, and if you change the exit() to drupal_exit(), it will also work great for Drupal 7 (currently it's a Drupal 6 snippet).

4
  • the file download is not working. what exit() exactly does? what if I dont write exit() because my function returns value on zip file creation Jun 5, 2012 at 10:44
  • 1
    The "application/octet-stream" is part of the forced download thing. If you use the proper MIME type, then the browser may decide to handle it instead of prompting for download.
    – mpdonadio
    Jun 5, 2012 at 10:46
  • @MPD Good point, I've updated the answer
    – Clive
    Jun 5, 2012 at 11:27
  • @subhojit777 exit() terminates the current script; running fpassthru() should be the last thing your script does, you should do any other processing you need to before-hand
    – Clive
    Jun 5, 2012 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.