Return 图片为 http-response 来自 Listener Symfony2

Return Image as http-response from Listener Symfony2

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

我想做的是,而不是显示错误消息“404 Not Found”return正确的图像。为此,我创建了一个数据库 table,用于存储已删除、移动或更改名称的图像的旧链接和新链接。

然后,此侦听器在数据库中找到 fallen 的链接并获取图像的新链接。目标是 return 将图像 http-response 与 header content-type 作为图像。

我的代码是:

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;

    ...
}
}

出现以下错误:

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

我可以对来自听众的 return 图片做些什么?谢谢

您问题中的代码片段几乎没有错误。

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

其次,不要自己发送响应,而是让框架来发送。 Symfony 事件系统是为灵活性而设计的(参见 the docs)。在您的情况下,在事件对象上设置响应就足够了。

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

此外,您可以使用 BinaryFileResponse 而不是标准 Response class。它的目的是提供文件(看看 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);
    }
}