1

I'm using passthru("cat filepath") in my download script. My concern is that it might use a lot of server resource.

What is the difference between directly link a file in a public directory and download a file using passthru("cat filepath") in php?

Moon
  • 22,195
  • 68
  • 188
  • 269

3 Answers3

4

What is the difference between directly link a file in a public directory and download a file using passthru("cat filepath") in php?

The difference is that linking directly to a file does not invoke PHP, while running a PHP script which in turn runs cat causes, well, both PHP and cat to be invoked. This will take up a moderate amount of extra memory, but won't cause server load under most circumstances.

I was using readfile(), but this function can't be used for files larger than 2gb

You might want to find a better solution than passing all of the file contents through PHP, in that case. Look into X-Sendfile support in your web server software of choice.

Charles
  • 50,943
  • 13
  • 104
  • 142
  • // Thank you for the suggestion. I've learned a new thing here. X-Sendfile! I will look for it. – Moon Jun 24 '11 at 07:17
  • // also..thank you for the performance suggestion. I was worrying about passthru causing a lot of load on the server side. – Moon Jun 24 '11 at 07:19
3

Don't use passthru() for that, you're opening yourself to CLI Injection and performance is terrible. readfile() exists just for that.

readfile($filepath);

There is a small overhead when passing through PHP compared to a direct link but we are usually talking of milliseconds. However, the browser will not be able to request a 206 Partial when using readfile() unless you code support for it or use something like PEAR::HTTP_Download.

EDIT: Seems you are using passthru() because apparently readfile() doesn't handle >2GB files properly (I never had that problem with readfile(), in fact I just tested it with a 7.2 GB file and it worked fine). In which case, at least escape your parameters.

function readfile_ext($filepath) {
  if(!file_exists($filepath))
    return false;

   passthru('cat ' . escapeshellarg($filepath));
   return true;
}
Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
  • @Andrew Moore // see my comment on deceze's post. – Moon Jun 24 '11 at 07:10
  • @Andrew Moore // Thank you for the suggestion. I will escape the variable. – Moon Jun 24 '11 at 07:17
  • @Moon: Note that I never had that 2GB problem with `readfile()`. Where did you read about that limitation? Did you test it? – Andrew Moore Jun 24 '11 at 07:30
  • @Andrew Moore // I've encountered an error with a large file. My previous question http://stackoverflow.com/questions/6463586/value-too-large-for-defined-data-type – Moon Jun 24 '11 at 07:38
  • @Andrew Moore // also, http://ca3.php.net/manual/en/function.fopen.php#37791 this is fopen function doc., but it looks like it applies to readfile as well. – Moon Jun 24 '11 at 07:39
2

Instead of passthru('cat filepath'), use the PHP native readfile('filepath'), which has better performance.

Both methods will be slower than simply directly linking to the file though, since PHP has a certain overhead.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • // i was using readfile(), but this function can't be used for files larger than 2gb – Moon Jun 24 '11 at 07:10
  • Serving a 2GB file via PHP is not very ideal to begin with. Do you require any PHP here? Couldn't your web server handle it directly? – deceze Jun 24 '11 at 07:13
  • // the files can't be placed in a public directory. I put files a private directory. So..I can't link them directly. – Moon Jun 24 '11 at 07:16