Search code examples
phpslimpsr-4slim-4

How to create new stream from Redis cache


I am storing image inside redis.

$image = $cache->remember($key, null, function () use ($request, $args) {
            $image = $this->get('image');
            $storage = $this->get('storage');

            return $image->load($storage->get($args['path'])->read())
                        ->withFilters($request->getQueryParams())
                        ->stream();
        });

and trying to get it back:

return (new Response())
                ->withHeader('Content-Type', 'image/png')
                ->withBody($image);

it gives me this error:

Return value of Slim\Handlers\Strategies\RequestResponse::__invoke() 
must implement interface Psr\Http\Message\ResponseInterface, string returned

$image variable is bytes of that image. how can I convert those bytes to a stream?


Solution

  • In order to create a stream from a string, you can use the Slim's implementation of Psr\Http\Message\StreamFactoryInterface (see PSR-17: HTTP Factories, or any other external library implementing the same interface (like laminas-diactoros).

    Using the Slim library, it should be something like this:

    <?php
    
    use Slim\Psr7\Response;
    use Slim\Psr7\Factory\StreamFactory;
    
    // The string to create a stream from.
    $image = $cache->remember($key, null, function () use ($request, $args) {
        //...
    });
    
    // Create the stream factory.
    $streamFactory = new StreamFactory();
    
    // Create a stream from the provided string.
    $stream = $streamFactory->createStream($image);
    
    // Create a response.
    $response = (new Response())
                    ->withHeader('Content-Type', 'image/png')
                    ->withBody($stream);
    
    // Do whatever with the response.
    

    Alternatively, you could use the method StreamFactory::createStreamFromFile:

    <?php
    
    // ...
    
    /*
     * Create a stream with read-write access:
     *
     *  'r+': Open for reading and writing; place the file pointer at the beginning of the file.
     *  'b': Force to binary mode.
     */
    $stream = $streamFactory->createStreamFromFile('php://temp', 'r+b');
    
    // Write the string to the stream.
    $stream->write($image);
    
    // ...