Programming

Symfony 7 — routing and controllers from scratch

Admin Główny 21.09.2026 419 wyświetleń 3 komentarzy
This translation was generated by AI and may contain inaccuracies. Read the original (PL)

Routing in Symfony 7

Symfony 7 uses PHP 8 attributes to define routes. This is far more readable than YAML or XML.

Basic controller

<?php

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: 'app_blog_index', methods: ['GET'])]
    public function index(): Response
    {
        return $this->render('blog/index.html.twig');
    }

    #[Route('/blog/{slug}', name: 'app_blog_show', methods: ['GET'])]
    public function show(string $slug): Response
    {
        // $slug is automatically injected from the URL
        return $this->render('blog/show.html.twig', ['slug' => $slug]);
    }
}

Parameter requirements

You can restrict the format of parameters using requirements:

#[Route(
    '/blog/{id}',
    name: 'blog_show_by_id',
    requirements: ['id' => '\d+'],
    methods: ['GET']
)]
public function showById(int $id): Response
{
    // ...
}

Route groups

The #[Route] attribute can also be set on the class — all routes in the controller inherit the prefix:

#[Route('/api/v1', name: 'api_v1_')]
class ApiController extends AbstractController
{
    #[Route('/users', name: 'users')]    // → /api/v1/users
    public function users(): JsonResponse { /* ... */ }
}

Dependency Injection in the controller

Constructor injection (recommended)

class ArticleController extends AbstractController
{
    public function __construct(
        private readonly ArticleRepository $articles,
        private readonly SluggerInterface  $slugger,
    ) {}

    #[Route('/articles')]
    public function index(): Response
    {
        $all = $this->articles->findPublished();
        return $this->render('article/index.html.twig', ['articles' => $all]);
    }
}

Action injection (for one-off dependencies)

#[Route('/articles/new')]
public function new(Request $request, EntityManagerInterface $em): Response
{
    // $request and $em injected only into this action
}

Returning data

Method Class When to use
render() Response HTML pages (Twig)
json() JsonResponse API endpoints
redirect() RedirectResponse Redirects
file() BinaryFileResponse File downloads

JSON example

#[Route('/api/articles', format: 'json')]
public function list(ArticleRepository $repo): JsonResponse
{
    return $this->json(
        $repo->findAll(),
        Response::HTTP_OK,
        [],
        ['groups' => 'article:list']
    );
}

Debugging routes

# list all routes
php bin/console debug:router

# details of a specific route
php bin/console debug:router app_blog_show

# match a URL to a route
php bin/console router:match /blog/my-article

Tip: In the development environment, the Symfony Profiler bar (at the bottom of the page) shows the current route, controller and execution time.

Tagi: #PHP #Symfony #Twig
Udostępnij: Facebook X LinkedIn

Komentarze (3)


J
Jan Kowalski 21.10.2026, 14:27

Świetne wyjaśnienie grup routingu. Używam prefiksów na /api i gra muzyka.

A
Anna Nowak 21.10.2026, 14:27

Warto dodać sekcję o route requirements z wyrażeniami regularnymi.

A
Admin Główny 21.10.2026, 14:27

Masz rację, dodam w następnej edycji. Dzięki za feedback!

Zaloguj się, aby dodać komentarz.