Hello,
Using Slim 4, PHP 7.3, how can I return (respond) files ?
In the action, I generate a PNG file, that I store on the disk, and I need to return the file ou redirect to an error page if there is an error.
Th.
Hello,
Using Slim 4, PHP 7.3, how can I return (respond) files ?
In the action, I generate a PNG file, that I store on the disk, and I need to return the file ou redirect to an error page if there is an error.
Th.
I wrote a tiny blog post for Slim 3. The principle is still the same. You just have to use your specific PSR-7 Stream object instead.
PS: Here is a new article for Slim 4:
Hello.
I’m lost.
I’ve tried:
private $streamFactory;
public function __construct(StreamFactoryInterface $streamFactory) {
$this->streamFactory = $streamFactory;
}
...
$stream = $this->streamFactory->createStreamFromFile($pngFilePath);
return $response->withBody($stream);
But I get this error:
Entry "Psr\Http\Message\StreamFactoryInterface" cannot be resolved: the class is not instantiable
I’ve also tried:
use Psr\Http\Message\StreamInterface as Stream;
$stream = fopen($pngFilePath, 'r');
return $response->withBody(new Stream($stream));
Error:
Cannot instantiate interface Psr\Http\Message\StreamInterface
It should work if you add a container definiton like this:
use Psr\Container\ContainerInterface;
use Psr\Http\Message\StreamFactoryInterface;
// ...
StreamFactoryInterface::class => function (ContainerInterface $container) {
return new \Slim\Psr7\Factory\StreamFactory();
},
Yes it works. Thanks…
My code, if it helps someone else in the future:
boot.php:
$containerBuilder = new ContainerBuilder();
$containerBuilder->addDefinitions(__DIR__ . '/../config/container.php');
container.php:
use Psr\Http\Message\StreamFactoryInterface;
use Slim\Psr7\Factory\StreamFactory;
return [
StreamFactoryInterface::class => function (Container $container) {
return new StreamFactory();
},
...
The controller creates an SVG file from a template (with variables), then generates the PNG file with Inkscape, then send the file.
My controller:
class GraphController {
private $streamFactory;
public function __construct(StreamFactoryInterface $streamFactory) {
$this->streamFactory = $streamFactory;
}
public getGraph() {
$pngFile = 'somepath/foo.png';
$svgFile = 'somepath/foo.svg';
ob_start();
include($graphs_dir . 'some-svg-template.php');
$include_svg = ob_get_contents();
ob_end_clean();
// DO NOT INDENT
$svg = <<< "SVG"
{$include_svg}
SVG;
$fichierSVG = fopen($svgFile, 'w+');
fputs($fichierSVG, '<?xml version="1.0" encoding="UTF-8" standalone="no"?>');
fputs($fichierSVG, "\n");
fputs($fichierSVG, $svg);
fclose($fichierSVG);
exec("inkscape --file=$svgFile --export-png=$pngFile --export-width=$size --export-height=$size", $out);
$stream = $this->streamFactory->createStreamFromFile($pngFile);
return $response
->withHeader('Content-Type', 'image/png')
->withBody($stream);