This library provides a Symfony responder class, which can be used to render a template, return json or a file and redirect to route/url.
This library is designed to be used in controllers which does not extend from AbstractController.
composer require oskarstark/symfony-http-responder
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Responder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/index', name: 'app_index')]
final class IndexController
{
public function __construct(
private Responder $responder,
) {
}
public function __invoke(): Response
{
return $this->responder->render('index.html.twig');
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Responder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/api', name: 'app_api')]
final class ApiController
{
public function __construct(
private Responder $responder,
) {
}
public function __invoke(): Response
{
$data = [
'foo' => 42,
];
return $this->responder->json($data);
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Responder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/download', name: 'app_download')]
final class DownloadController
{
public function __construct(
private Responder $responder,
) {
}
public function __invoke(): Response
{
// You can either provide a filepath
$file = '/app/invoices/invoice.pdf';
// or an SplFileObject
$file = new \SplFileObject('/app/invoices/invoice.pdf');
return $this->responder->file($file);
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Responder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/redirect', name: 'app_redirect')]
final class RedirectController
{
public function __construct(
private Responder $responder,
) {
}
public function __invoke(): Response
{
return $this->responder->redirect('http://google.com');
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Responder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/redirect', name: 'app_redirect')]
final class RedirectController
{
public function __construct(
private Responder $responder,
) {
}
public function __invoke(): Response
{
return $this->responder->route('app_my_route');
}
}
Symfony can respond using PSR-7 Response Interface instances when we are using the symfony/psr-http-message-bridge package, as described in this blog post.
# config/packages/oskarstark_symfony_http_responder.yaml
services:
# ...
OskarStark\Symfony\Http\Psr7Responder: null
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Psr7Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\Routing\Annotation\Route;
final class RedirectHandler implements RequestHandlerInterface
{
public function __construct(
private Psr7Responder $responder,
) {
}
#[Route('/index', name: 'app_index')]
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->responder->render('index.html.twig');
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Psr7Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\Routing\Annotation\Route;
final class RedirectHandler implements RequestHandlerInterface
{
public function __construct(
private Psr7Responder $responder,
) {
}
#[Route('/api', name: 'app_api')]
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->responder->json($data);
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Psr7Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\Routing\Annotation\Route;
final class RedirectHandler implements RequestHandlerInterface
{
public function __construct(
private Psr7Responder $responder,
) {
}
#[Route('/download', name: 'app_download')]
public function handle(ServerRequestInterface $request): ResponseInterface
{
// You can either provide a filepath
$file = '/app/invoices/invoice.pdf';
// or an SplFileObject
$file = new \SplFileObject('/app/invoices/invoice.pdf');
return $this->responder->file($file);
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Psr7Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\Routing\Annotation\Route;
final class RedirectHandler implements RequestHandlerInterface
{
public function __construct(
private Psr7Responder $responder,
) {
}
#[Route('/redirect', name: 'app_redirect')]
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->responder->redirect('http://google.com');
}
}
<?php
declare(strict_types=1);
namespace App\Controller;
use OskarStark\Symfony\Http\Psr7Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\Routing\Annotation\Route;
final class RedirectHandler implements RequestHandlerInterface
{
public function __construct(
private Psr7Responder $responder,
) {
}
#[Route('/redirect', name: 'app_redirect')]
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->responder->route('app_my_route');
}
}