Streaming Tar Files the Right Way in PHP

Tonight I was working on on-the-fly tarring of files, and in the spirit of not-reinventing-the-wheel, a quick search turned up a just written article, Creating ZIP and TAR archives on the fly with PHP. Great!

Except that when you think about it, TAR (that stands for Tape ARchiver) is built for streaming. It just doesn’t make any sense to create a temp file and then send it – that seems like a waste (unless you were streaming the same file many, many times or using a separate set of servers for sending static files). If you’re going to be sending a file with the same Apache processes, here’s the right way (well, my right way, YMMV) of on-the-fly creation:

// Unlimited execution, as long as it takes to DL
set_time_limit(0);

// For proper browser handling
header('Content-type: application/x-tar');
header('Content-Disposition: attachment; filename="' . $filename . '.tar"');

// Make it safe
$filename = escapeshellarg($filename);

// the C argument is so that doesn't get included in your tarball extraction
$cmd = "tar cC /path/to/tar/from $filename";

// teh magic
$fh = popen($cmd, 'r');
while (!feof($fh)) {
  print fread($fh, 8192);
}
pclose($fh);