Is there a better way how to force file download than using this simple PHP script? I've written this simple script to force download some files (jpg, mp3, usually those which are loaded in browser by default).
I was wondering whether there's any way this could be improved upon, which means:


making it more secure
making it use less cpu (filesize(), fopen(), fpassthru() are the usual suspects here)
making it simpler maybe


Here it goes:

&lt;?php

if (!isset($_GET['file'])){
   die('no file requested');
}

else{

   if (substr($_GET['file'], 0, 1) == '.'){
      die('trying to leave this directory? :)');
   }

   $path = './'.$_GET['file'];
   if (file_exists($path) &amp;&amp; is_readable($path)){
    $size = filesize($path);
    header('Content-Type: application/octet-stream');
    header('Content-Length: '.$size);
    header('Content-Disposition: attachment; filename='.$_GET['file']);
    header('Content-Transfer-Encoding: binary');
    $file = fopen($path, 'rb');
    fpassthru($file);
    exit;
   }

}

?&gt;


Usage: /?file=sample.jpg
Always use === in your comparisons.

if (substr($_GET['file'], 0, 1) == '.'){
  die('trying to leave this directory? :)');
}


Should be:

if (substr($_GET['file'], 0, 1) === '.'){
  die('trying to leave this directory? :)');
}


Also look into other ways to sanitize $_GET['file'] properly at the moment I could pass in something like /../ and I could access other files.

From the docs you can save on a fopen() call by using readfile() instead see fpassthru()

A better way to use variables in a string is to use curly syntax so this line

header('Content-Disposition: attachment; filename='.$_GET['file']);


Would be better as

header("Content-Disposition: attachment; filename={$_GET['file']}");


I think that covers the three bullet points :)