0
votes

I want to serve several images which are not avaible in public folder (web) using php for example path/to/myphp/script.php?image=imagereference&some=parameter

To improve performances and not using this approach I made a twig extension to do that.

<?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;
    }
}

And into my twig template

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

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

But it doesn't work because the response returned is not a valid src path.

The only way I found is to base 64 encode the response returned

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

So my question is how generate URL that target my twig extension?

Something like path/to/twigExtension.php?ref=ref calls show(ref)

Maybe it's not the good way to achieve that.

1
Think about it: generate URL that target my twig extension this basically means "where do I send my http request to". In the end it makes no difference, to handle a http request you'll need a controller. Using a twig extension here only makes a difference if whatever that extension does prevents the extra round trip to the server (e.g. your base64 approach). If you need performance you'll need to by-pass the php layer. Let the http server serve the image from a static source.Yoshi
I totally agree with that, but as I mentionned it ( I guess ..) I need to do some check as determine available format for specific user, do I need to apply watermark or not and some others checks. base64 encode approach is good in performance speed but my images are too heavy (e.g. 70ko average) to use this approachakio
I understand, what I tried to imply is that, if you need to go trough php, it makes no difference whether you handle it in a twig extension or a simple controller. Honestly, I'd only use a twig extension here to ease url generation, but then handle the actual request in a controller. Performance-wise you could either cache (as mentioned below) the result server-side or maybe send appropriate cache-headers to the client.Yoshi

1 Answers

0
votes

This is a two step process.

  1. you need to create to a valid link to each image (which will be a route to some kind of ImageController::show(id) controller-action)

  2. The ImageController that takes the id (or imagename) and shouts out the binary content of the image file (or throws an error if a user is not granted to download the image). You can return a BinaryFileResponse here. Take a look here.