我的Symfony2应用程序允许用户上传文件。我希望用户也能够下载他们的文件。
如果我直接使用PHP,我只输出相应的标题,然后输出文件的内容。我如何在Symfony2控制器中执行此操作?
(如果你在答案中使用了硬编码的文件名,这对我来说已经足够了。)
答案 0 :(得分:15)
我最终这样做了:
/**
* 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);
}
答案 1 :(得分:2)
您不想完全绕过Symfony而只是通过HTTP服务器(Apache,Nginx等)提供文件的原因?
只需将上传的文件放在文档根目录中,让您的HTTP服务器尽其所能。
更新:虽然@ Jason Swett发布的Symfony2代码适用于99%的案例 - 我只是想确保记录备选方案。另一种保护下载的方法是使用Lighttpd的mod_secdownload
模块。对于较大的文件或文件来说,这将是一个理想的解决方案,需要尽可能少地使用内存来快速提供。
答案 2 :(得分:0)
它允许你这样做:
/**
* @param integer $assetId
*
* @return Response
*/
public function downloadAssetAction($assetId)
{
if (!$courseAsset = $this->get('crmpicco.repository.course_asset')->findOneById($assetId)) {
throw new NotFoundHttpException('Requested asset (' . $assetId . ') does not exist.');
}
$downloadHandler = $this->get('vich_uploader.download_handler');
return $downloadHandler->downloadObject($courseAsset->getFile(), 'assetFile', null, $courseAsset->getName());
}