20

i created with php zip ( http://php.net/manual/de/book.zip.php ) a zip file

now i have to send it to the browser / force a download for it.

Martin Huwa
  • 401
  • 3
  • 7
  • 11
  • possible duplicate of [Any way to force download a remote file?](http://stackoverflow.com/questions/531292/any-way-to-force-download-a-remote-file) – cweiske Sep 19 '11 at 12:33

4 Answers4

47
<?php
    // or however you get the path
    $yourfile = "/path/to/some_file.zip";

    $file_name = basename($yourfile);

    header("Content-Type: application/zip");
    header("Content-Disposition: attachment; filename=$file_name");
    header("Content-Length: " . filesize($yourfile));

    readfile($yourfile);
    exit;
?>
Amber
  • 507,862
  • 82
  • 626
  • 550
6

If you already have your ZIP on the server, and if this ZIP is reachable by Apache in HTTP or HTTPS, then, you should redirect to this file instead of "reading it" with PHP.

It's much more efficient as you don't use PHP, so no CPU or RAM are needed, and it will be faster to download, as no reading/writing by PHP needed too, only direct download. Let's Apache do the job!

So a nice function could be:

if($is_reachable){
    $file = $relative_path . $filename; // Or $full_http_link
    header('Location: '.$file, true, 302);
}
if(!$is_reachable){
    $file = $relative_path . $filename; // Or $absolute_path.$filename
    $size = filesize($filename); // The way to avoid corrupted ZIP
    header('Content-Type: application/zip');
    header('Content-Disposition: attachment; filename=' . $filename);
    header('Content-Length: ' . $size);
    // Clean before! In order to avoid 500 error
    ob_end_clean();
    flush();
    readfile($file);
}
exit(); // Or not, depending on what you need

I hope that it will help.

XDjuj
  • 103
  • 1
  • 5
  • ob_end_clean(); – zod Jul 26 '17 at 23:01
  • Where `$is_reachable` comes from...? – Andrei Surdu Jan 05 '18 at 13:41
  • 1
    Hi Andrei. From where you want! It can be a test from your own, depending on how is written your code. For example, if you now that the ZIP already exists (because you don't have to generate it for example) AND is accessible with a direct link (no authorization required). To resume: if you can download with a direct link the ZIP is reachable, if not (authentication, stranges links or whatever), you need to "force" the download with PHP. – XDjuj Jan 08 '18 at 13:52
6

Set the content-type, content-length and content-disposition headers, then output the file.

header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Length: '.filesize($filepath) );
readfile($filepath);

Setting Content-Disposition: attachment will suggest the browser to download the file instead of displaying it directly.

Kaivosukeltaja
  • 15,541
  • 4
  • 40
  • 70
2

You need to do it this way, otherwise your zip will be corrupted:

$size = filesize($yourfile);
header("Content-Length: \".$size.\"");

So content-length header needs a real string, and filesize returns and integer.

Roger
  • 39
  • 1
  • 3
    thank you for this comment, I waisted hours on corrupt zip file because I was using header('Content-Length: '.filesize($filepath) ); Your solution works better. – niko craft Oct 20 '16 at 15:48