【问题标题】:Symfony 3 - Serve image within twig extensionSymfony 3 - 在树枝扩展中提供图像
【发布时间】:2019-12-24 15:38:38
【问题描述】:

我想使用 php 提供几个在公共文件夹(网络)中不可用的图像,例如 path/to/myphp/script.php?image=imagereference&some=parameter

为了提高性能而不是使用this approach,我做了一个树枝扩展来做到这一点。

<?php

#src/MyBundle/Service/DisplayImage.php

namespace MyBundle\Service;

#https://symfony.com/blog/new-in-symfony-2-4-the-request-stack
use Symfony\Component\HttpFoundation\RequestStack;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;

class DisplayImage
{
    private $entityManagerInterface;
    private $requestStack;

    public function __construct(EntityManagerInterface $entityManagerInterface, RequestStack $requestStack)
    {
        $this->entityManagerInterface = $entityManagerInterface;
        $this->requestStack = $requestStack;
    }

    public function show(int $ref)
    {
        $photoPath = __DIR__ ."/../photoFolder/".$ref.".jpg";
        $file = file_get_contents($photoPath);
        
        $response = new Response();
        $response->headers->set('Content-Type', 'image/jpeg');
        $response->setContent($file);
        return $response;
    }
}

进入我的树枝模板

{# src/MyBundle/Ressources/views/DisplayImage.html.twig #}

{% for ref in refs %}
  <img src="{{ show(ref) }}"/>
{% endfor %}

但它不起作用,因为返回的响应不是有效的 src 路径。

我发现的唯一方法是对返回的响应进行 base 64 编码

<?php
return "data:image/jpeg;base64," . base64_encode($file);

所以我的问题是如何生成针对我的树枝扩展的 URL?

类似path/to/twigExtension.php?ref=ref 调用show(ref)

也许这不是实现这一目标的好方法。

【问题讨论】:

  • 想一想:生成以我的 twig 扩展为目标的 URL 这基本上意味着“我将我的 http 请求发送到哪里”。最后没有区别,要处理一个http请求,你需要一个控制器。在这里使用 twig 扩展只会在该扩展阻止额外往返服务器的情况下产生影响(例如,您的 base64 方法)。如果您需要性能,则需要绕过 php 层。让 http 服务器从静态源中提供图像。
  • 我完全同意这一点,但正如我所提到的(我猜..)我需要做一些检查以确定特定用户的可用格式,我是否需要应用水印以及其他一些检查。 base64 编码方法的性能速度不错,但我的图像太重(例如平均 70ko)无法使用这种方法
  • 我明白,我试图暗示的是,如果你需要通过 php,无论你是在树枝扩展还是简单的控制器中处理它都没有区别。老实说,我只会在此处使用树枝扩展来简化 url 生成,然后在控制器中处理实际请求。性能方面,您可以在服务器端缓存(如下所述)结果,也可以将适当的缓存头发送到客户端。

标签: php symfony twig


【解决方案1】:

这是一个两步过程。

  1. 您需要创建到每个图像的有效链接(这将是某种 ImageController::show(id) 控制器动作的路由)

  2. ImageController 获取 id(或图像名称)并输出图像文件的二进制内容(如果未授予用户下载图像的权限,则会引发错误)。您可以在此处返回 BinaryFileResponse。看看here。

【讨论】:

  • 该过程确实有效,但我有几张图片要显示(我说的是每页近 50 张图片)所以这种方法在性能上不够高效,这就是我使用 twig 扩展的原因,我阅读这是提高性能的最佳方法
  • 您可以使用 twig 扩展来为每张图片呈现正确的 URI,但这对性能没有太大帮助。我建议看看 LiipImagineBundle {github.com/liip/LiipImagineBundle},它可以帮助您以较低的分辨率和格式缓存图像以加快加载速度。
  • 如果您喜欢,您可以使用 javascript 和 ajax 一张一张替换图片以获得更高的分辨率。或者,如果您愿意,也可以使用称为延迟加载 (imagekit.io/blog/lazy-loading-images-complete-guide) 的技术。
  • 我无法缓存图像,因为我必须限制存储空间。我的应用是 DAM,有近百万张图片
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多