Skip to content

Serving BIG Files Through PHP

There are many reasons why you would want to serve big files through an application server:

  • Restricting access of certain files to the registered users only
  • Serving digital goods after successful payment

The easiest way would be using “readfile()”.

<?php
//check if user is $loggedin
if ($loggedin) {
    $filename = "path/to/file";
    $mimetype = "mime/type";
    header("Content-Type: ".$mimetype );
    echo readfile($filename);
}
else {
    echo "Please login first!";
}
?>

This code should work fine if you are only serving files that are small. The readfile() function loads the file into memory for every request. This means serving big files or many files at the same time could have a big impact on your server’s performance. And in my opinion this should NOT be used even for small files!

There is a better way to serve files wihtout having much impact on your server and that’s using what’s called “internal redirect”.

If your server is Apache or Lighttpd, use X-Sendfile header.

<?php
//check if user is $loggedin
if ($loggedin) {
    $filename = "path/to/file";
    header("Content-Disposition: attachment; filename = ".$filename);
    header("X-Sendfile: ".$filename);
}
else {
    echo "Please login first!";
}
?>

If your server is LiteSpeed, use X-LiteSpeed header.

<?php
//check if user is $loggedin
if ($loggedin) {
    $filename = "path/to/file";
    header("Content-Disposition: attachment; filename = ".$filename);
    header("X-LiteSpeed: ".$filename);
}
else {
    echo "Please login first!";
}
?>

and finally if your server is NGINX, use X-Accel-Redirect header.

<?php
//check if user is $loggedin
if ($loggedin) {
    $filename = "path/to/file";
    header("Content-Disposition: attachment; filename = ".$filename);
    header("X-Accel-Redirect: ".$filename);
}
else {
    echo "Please login first!";
}
?>

Now you can sell BIG digital assets in your website.