Controllers
A controller receives a request and returns a response — always a Response object. The AbstractController base class gives short methods for common jobs: render a template, redirect, return JSON.
Creating
php bin/console make:controller BlogControllerThe command creates a class and a template for it:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class BlogController extends AbstractController
{
#[Route('/blog', name: 'blog_index')]
public function index(): Response
{
return $this->render('blog/index.html.twig', [
'title' => 'Blog',
]);
}
}render() finds the template in the templates folder and passes variables to it.
The request
Request data lives in the Request object. Just add it to the method's arguments:
use Symfony\Component\HttpFoundation\Request;
#[Route('/search', name: 'search')]
public function search(Request $request): Response
{
$query = $request->query->get('q', '');
$page = $request->query->getInt('page', 1);
return new Response("Searching: $query, page $page");
}| Property | What it holds |
|---|---|
$request->query | Address parameters after ? |
$request->request | Fields of a form sent with POST |
$request->files | Uploaded files |
$request->headers | Headers |
$request->cookies | Cookies |
Redirecting
return $this->redirectToRoute('blog_show', ['slug' => 'first-post']);JSON
#[Route('/api/status', name: 'api_status')]
public function status(): Response
{
return $this->json(['status' => 'ok', 'time' => time()]);
}The 404 error
#[Route('/blog/{slug}', name: 'blog_show')]
public function show(string $slug, PostRepository $posts): Response
{
$post = $posts->findOneBy(['slug' => $slug]);
if (!$post) {
throw $this->createNotFoundException('Post not found');
}
return $this->render('blog/show.html.twig', ['post' => $post]);
}PostRepository in the arguments is a service: Symfony passes the right object by its type.
Messages after an action
A message is stored in the session and shown once — on the next page:
$this->addFlash('success', 'The post was saved');
return $this->redirectToRoute('blog_index');{% for message in app.flashes('success') %}
<div class="alert">{{ message }}</div>
{% endfor %}Common mistake
A controller method must return a Response object. If you forget return before $this->render(...) or return a string or an array, Symfony reports: The controller must return a "Response" object. Put the : Response type on every method — then the editor shows the error first.