26

I want to serve an existing file to the browser in PHP. I've seen examples about image/jpeg but that function seems to save a file to disk and you have to create a right sized image object first (or I just don't understand it :))

In asp.net I do it by reading the file in a byte array and then call context.Response.BinaryWrite(bytearray), so I'm looking for something similar in PHP.

Michel

6 Answers 6

44

There is fpassthru() that should do exactly what you need. See the manual entry to read about the following example:

<?php

// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;

?>

See here for all of PHP's filesystem functions.

If it's a binary file you want to offer for download, you probably also want to send the right headers so the "Save as.." dialog pops up. See the 1st answer to this question for a good example on what headers to send.

Sign up to request clarification or add additional context in comments.

3 Comments

What if I already have binary content stored as a variable. How do I output it to the browser as a downloadable file?
I try doing this with a .svg file (textfile) but the browser downloads a php-file instead of showing svgfile (image) I changed Content-Type to image/svg
It worked better with Content-Type image/svg+xml but now it complains that xml declaration starts at line 2
16

I use this

  if (file_exists($file)) {


        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));

        ob_clean();
        flush();
        readfile($file);
        exit;

    } 

Comments

3

I use readfile() ( http://www.php.net/readfile )...

But you have to make sure you set the right "Content-Type" with header() so the browser knows what to do with the file.

You can also force the browser to download the file instead of trying to use a plug-in to display it (like for PDFs), I always found this to look a bit "hacky", but it is explained at the above link.

Comments

2

This should get you started: http://de.php.net/manual/en/function.readfile.php

Edit: If your web server supports it, using

header('X-Sendfile: ' . $filename);

where file name contains a local path like

/var/www/www.example.org/downloads/example.zip

is faster than readfile().

(usual security considerations for using header() apply)

Comments

1

For both my website and websites I create for clients I use a PHP script that I found a long time ago.

It can be found here: http://www.zubrag.com/scripts/download.php

I use a slightly modified version of it to allow me to obfuscate the file system structure (which it does by default) in addition to not allowing hot linking (default) and I added some additional tracking features, such as referrer, IP (default), and other such data that I might need should something come up.

Hope this helps.

1 Comment

Thanks for the script. If i want to expand my first script i'll definately will use it.
1

Following will initiate XML file output

$fp = fopen($file_name, 'rb');

// Set the header
header("Content-Type: text/xml");
header("Content-Length: " . filesize($file_name));
header('Content-Disposition: attachment; filename="'.$file_name.'"');

fpassthru($fp);
exit;

The 'Content-Disposition: attachment' is pretty common and is used by sites like Facebook to set the right header

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.