Let’s say you are running a report for the user. You generate some temporary file to give to the user and now you have this zombie pdf file sitting out there in your /tmp directory. How do you clean it up? Why not do it directly after you serve to the user? Here are a couple of options. The first option just cleans up the file after the application has served the response.
Route::get('get-file', function()
{
$filename = storage_path() . '/testing.txt';
App::finish(function($request, $response) use ($filename)
{
unlink($filename);
});
return Response::download($filename);
});
If you don’t like the idea of putting App::finish
in your controller action or route closure then you could always use a helper to do your downloads. This will let you call: ResponseHelper::downloadAndDelete($filename);
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
class ResponseHelper extends Illuminate\Support\Facades\Response
{
static public function downloadAndDelete($fileName, $name = null, array $headers = array())
{
$file = new File((string) $fileName);
$base = $name ?: basename($fileName);
$content = file_get_contents($fileName);
$response = Response::make($content);
if (!isset($headers['Content-Type']))
{
$headers['Content-Type'] = $file->getMimeType();
}
if (!isset($headers['Content-Length']))
{
$headers['Content-Length'] = $file->getSize();
}
if (!isset($headers['Content-disposition']))
{
$headers['Content-disposition'] = 'attachment; filename=' . $base;
}
foreach ($headers as $headerName => $headerValue)
{
$response->header($headerName, $headerValue);
}
unlink($fileName);
return $response;
}
}
Finally, another idea is to register your App::finished
closures in another class or as event listeners. I’ll leave that up to you to implement.