Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serve a download of an uploaded file in Symfony2

Tags:

symfony

My Symfony2 app allows users to upload files. I'd like to users to also be able to download their files.

If I were doing straight PHP, I'd just output the appropriate headers, then output the contents of the file. How would I do this within a Symfony2 controller?

(If you use a hard-coded filename in your answer, that's good enough for me.)

like image 891
Jason Swett Avatar asked Apr 01 '12 21:04

Jason Swett


2 Answers

I ended up doing this:

/** 
 * Serves an uploaded file.
 *
 * @Route("/{id}/file", name="event_file")
 * @Template()
 */
public function fileAction($id)
{   
    $em = $this->getDoctrine()->getEntityManager();

    $entity = $em->getRepository('VNNPressboxBundle:Event')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Event entity.');
    }   

    $headers = array(
        'Content-Type' => $entity->getDocument()->getMimeType(),
        'Content-Disposition' => 'attachment; filename="'.$entity->getDocument()->getName().'"'
    );  

    $filename = $entity->getDocument()->getUploadRootDir().'/'.$entity->getDocument()->getName();

    return new Response(file_get_contents($filename), 200, $headers);
}   
like image 124
Jason Swett Avatar answered Oct 17 '22 01:10

Jason Swett


Any reason why you do not want to bypass Symfony entirely and just serve the file via your HTTP server (Apache, Nginx, etc)?

Just have the uploaded files dropped somewhere in the document root and let your HTTP server do what it does best.

Update: While the Symfony2 code posted by @Jason Swett will work for 99% of cases - I just wanted to make sure to document the alternative(s). Another way of securing downloads would be to use the mod_secdownload module of Lighttpd. This would be the ideal solution for larger files or files that need to be served quickly with little-as-possible memory usage.

like image 25
leek Avatar answered Oct 17 '22 01:10

leek