本文概述
- 返回一个动态创建的文件
- Symfony 3.2
A.在浏览器中返回文件
【如何从Symfony 3中的控制器发送文件作为响应】你可以返回要在浏览器中查看的文件(如果支持), 因为它没有自定义内容配置, 因此直接返回BinaryFileResponse类:
<
?phpnamespace myBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Import the BinaryFileResponseuse Symfony\Component\HttpFoundation\BinaryFileResponse;
class DefaultController extends Controller{public function indexAction(){// You only need to provide the path to your static file// $filepath = 'path/to/TextFile.txt';
// i.e Sending a file from the resources folder in /web// in this example, the TextFile.txt needs to exist in the server$publicResourcesFolderPath = $this->
get('kernel')->
getRootDir() . '/../web/public-resources/';
$filename = "TextFile.txt";
// This should return the file located in /mySymfonyProject/web/public-resources/TextFile.txt// to being viewed in the Browserreturn new BinaryFileResponse($publicResourcesFolderPath.$filename);
}}
如果你确定返回的文件不会在浏览器中查看, 而是会下载, 则也可以使用上一个代码段。但是, 如果需要下载文件, 我们建议你强制文件的模仿, 并将内容处置设置为附件, 如以下示例所示。
B.返回文件下载
有时, 你需要返回要在控制器中下载的文件, 因此需要使用BinaryFileResponse类, 但是需要修改响应的处理方式, 并在标题中添加将要下载的文件的模仿类型。这非常适合你希望客户下载而不是在线阅读的文件, 例如PDF, 文档文件, 图像和视频:
<
?phpnamespace myBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Import required classesuse Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser;
class DefaultController extends Controller{public function indexAction(){// You only need to provide the path to your static file// $filepath = 'path/to/TextFile.txt';
// i.e Sending a file from the resources folder in /web// in this example, the TextFile.txt needs to exist in the server$publicResourcesFolderPath = $this->
get('kernel')->
getRootDir() . '/../web/public-resources/';
$filename = "TextFile.txt";
// This should return the file to the browser as response$response = new BinaryFileResponse($publicResourcesFolderPath.$filename);
// To generate a file download, you need the mimetype of the file$mimeTypeGuesser = new FileinfoMimeTypeGuesser();
// Set the mimetype with the guesser or manuallyif($mimeTypeGuesser->
isSupported()){// Guess the mimetype of the file according to the extension of the file$response->
headers->
set('Content-Type', $mimeTypeGuesser->
guess($publicResourcesFolderPath.$filename));
}else{// Set the mimetype of the file manually, in this case for a text file is text/plain$response->
headers->
set('Content-Type', 'text/plain');
}// Set content disposition inline of the file$response->
setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
return $response;
}}
如你所见, 在以下示例中, 如果支持, 则使用FileinfoMimeTypeGuesser类猜测要下载的文件的MIME类型, 否则, 你需要手动提供MIME类型。
BinaryFileResponse将自动处理请求中的Range和If-Range标头。它还支持X-Sendfile(有关Nginx和Apache, 请参见)。取决于应用程序标头的静态文件的传递称为X-Sendfile功能。要使用它, 你需要确定是否应该信任X-Sendfile-Type标头, 如果使用以下方法, 请调用trustXSendfileTypeHeader():
BinaryFileResponse::trustXSendfileTypeHeader();
返回一个动态创建的文件发送动态创建的文件时, 必须将Content-Disposition标头添加到响应中。在常规HTTP响应中, Content-Disposition响应标头是一个标头, 用于指示内容是否应在浏览器中内联显示, 即作为网页还是作为网页的一部分, 或作为此附件中的附件情况下, 将其下载并保存在本地。在这种情况下, 我们的文件不存在于服务器的存储中, 而是存在于内存和变量中。
虽然为基本文件下载创建此标头很容易, 但使用非ASCII文件名则涉及更多。 makeDisposition()抽象了简单API背后的艰苦工作:
<
?phpnamespace myBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Include the Response and ResponseHeaderBaguse Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
class DefaultController extends Controller{public function indexAction(){// Provide a name for your file with extension$filename = 'TextFile.txt';
// The dinamically created content of the file$fileContent = "Hello, this is the content of my File";
// Return a response with a specific content$response = new Response($fileContent);
// Create the disposition of the file$disposition = $response->
headers->
makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
// Set the content disposition$response->
headers->
set('Content-Disposition', $disposition);
// Dispatch requestreturn $response;
}}
前一个控制器的indexAction的执行应在浏览器中自动生成一个文本文件的下载, 文件名为TextFile, 扩展名为.txt。如果要直接在浏览器中查看文件, 可以将ResponseHeaderBag :: DISPOSITION_ATTACHMENT更改为ResponseHeaderBag :: DISPOSITION_INLINE。
Symfony 3.2随着Symfony 3.2的发布, 控制器上有一个新方法, 即file, 它强制在浏览器中下载文件:
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
public function fileAction(){// load the file from the filesystem$file = new File('/path/to/some_file.pdf');
return $this->
file($file);
// rename the downloaded filereturn $this->
file($file, 'custom_name.pdf');
// display the file contents in the browser instead of downloading itreturn $this->
file('invoice_3241.pdf', 'my_invoice.pdf', ResponseHeaderBag::DISPOSITION_INLINE);
}
玩得开心 !
推荐阅读
- 如何在Symfony 3中从图像中提取突出的颜色
- Symfony ubuntu(尝试从全局名称空间加载类”DOMDocument”)
- 如何使用自己的Symfony 3 API解决客户端”Access-Control-Allow-Origin”请求错误
- 如何在Symfony 3中使用FOSUserBundle向用户添加角色
- 如何在Symfony 3中使用FOSUserBundle创建自定义登录事件(onLogin)监听器
- 在PHP中正确创建URL标记(包括UTF-8的音译)
- 如何使用纯PHP重定向到页面
- 如何使用C#在WinForms中实现和使用循环进度条
- Android(背景颜色和图像同时)