Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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 BlogController

The 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");
}
PropertyWhat it holds
$request->queryAddress parameters after ?
$request->requestFields of a form sent with POST
$request->filesUploaded files
$request->headersHeaders
$request->cookiesCookies

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.

Thanks for reading!

Donate to the site — we work hard for you.