Serve then remove temporary file using Laravel

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.

post by Kelt Dockins on 03/20/2014