将图像作为来自Listener Symfony2的http响应返回

时间:2016-01-22 21:46:37

标签: image symfony http-headers listener imagesource

此监听器向我发送有关网站上发生的各种异常的报告。有时我会收到已删除但仍被搜索引擎和其他人查询过的图像的报告。

我想这样做,而不是显示错误消息"找不到404"返回正确的图像。为此,我创建了一个数据库表,用于存储已删除,移动或更改其名称的图像的旧链接和新链接。

然后,这个监听器在db中找到掉落的链接并获取新的图像链接。目标是将图像作为http-response返回,标题内容类型为图像。

我的代码是:

class ExceptionListener
{
private $service_container;
private $router;

function __construct(Container $service_container, $router){
    $this->service_container = $service_container;
    $this->router = $router;
}

public function onKernelException(GetResponseForExceptionEvent $event){
    $exception = $event->getException();
    $request = $this->service_container->get('request');

    ...

    $document_root = $request->server->get('DOCUMENT_ROOT');
    $filename = realpath($document_root . '/'. '/path/to/new_image.jpg');
    $response = new \Symfony\Component\HttpFoundation\Response();
    $response->headers->set('Content-type',  'image/jpeg');
    $response->headers->set('Content-Disposition', 'inline; filename="' . basename($filename) . '";');
    $response->headers->set('Content-length', filesize($filename));
    $response->sendHeaders();
    $response->setContent(file_get_contents($filename));
    return $response;

    ...
}
}

发生以下错误:

browser screenshot

在浏览器中,您可以看到一个小方框,就好像试图显示图像但无法获得图像源。但是如果在控制器上测试相同的代码,它的工作正常并显示图像。

in controller works fine

如何从聆听者处返回图像?感谢

1 个答案:

答案 0 :(得分:1)

您的问题中的代码段存在一些问题。

首先,您永远不应该使用请求服务。 It's deprecated since Symfony 2.4 and was removed in Symfony 3.0。请改为使用请求堆栈(request_stack)。

其次,不要自己发送响应,但让框架去做。 Symfony事件系统旨在提供灵活性(请参阅the docs)。在您的情况下,它足以在事件对象上设置响应。

最后,您根本不需要服务容器来访问请求,因为它可以在the event上找到。

此外,您可以使用BinaryFileResponse而不是标准的Res​​ponse类。它的目的是提供文件(看看the docs)。

您可以大大简化您的听众:

use Symfony\Component\HttpFoundation\BinaryFileResponse;

class ExceptionListener
{
    private $router;

    function __construct($router)
    {
        $this->router = $router;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $exception = $event->getException();
        // request is avialable on the event
        $request = $event->getRequest();

        // ...


        $file = 'path/to/file.txt';
        $response = new BinaryFileResponse($file);
        // ... set response parameters ...

        // finally, set the response on your event
        $event->setResponse($response);
    }
}