我通过控制器提供受保护的图像,以便我可以在需要时从公共视图中禁用其中一些图像。因此,我使用BinaryFileResponse,实际上直接从Nginx提供图像 这是控制器:
public function getPictureAction(Request $request, $id)
{
$image = $this->getDoctrine()
->getRepository('AppBundle:Images')
->getOneById($id);
$dir = $this->get('kernel')->getRootDir() . '/';
// Serving image by using Nginx's 'XSendfile'
$request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
$request->headers->set('X-Accel-Mapping', $dir . '=/images-internal/');
BinaryFileResponse::trustXSendfileTypeHeader();
$path = $dir . 'images/image.jpg';
$response = new BinaryFileResponse($path);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);
return $response;
}
启用了X-Accel-Redirect的nginx配置的一部分:
location /images-internal/ {
internal;
alias /home/vagrant/Sites/Symfony/app/;
}
路由在routing.yml:
picture_path:
path: /images/{id}
defaults: {_controller: AppBundle:Pages/Home:getPicture, _format: html}
methods: [GET]
options:
expose: true
在Twig模板中,我像这样加载图像:
<img src="{{ path('picture_path', {'id': imageId}) }}">
使用此设置, 53KB 图像的平均加载时间约为 700ms 。
出于测试目的,我使用来自公共网站目录的Twig的AssetExtension加载了相同的图像:
<img src="{{ asset('bundles/img/image.jpg') }}">
加载时间 30ms !
通过控制器加载图像需要这么长时间是正常的,还是我做错了什么?
答案 0 :(得分:2)
这取决于其他控制器的加载时间。我的意思是控制器返回常规响应,而不是二进制。如果它们的加载时间是700毫秒或更长,这是正常的。
从公共网站目录加载图片很快,因为只涉及网络服务器(nginx)。
通过控制器加载图像涉及web-server(nginx),php,symfony。因此,ussualy需要与常规控制器的请求相同的时间。
X-Accel-Redirect
在这种情况下没有多大帮助,它通常用于大文件来释放php进程。 Php进程发送此头并终止处理,然后nginx读取并发送文件。
如果你想加快图片加载尝试安装php opcache或在没有symfony的纯php上编写脚本来处理图像下载。