🏛️ Introduction à Symfony

Votre premier pas dans le framework PHP professionnel

Installation • Structure • Routing • Contrôleurs • Twig • Console

Formation DWWM - 2026

Au programme 📋

# 🎯 Partie 0

Qu'est-ce que Symfony ?

Comprendre avant de coder

C'est quoi Symfony ? 🏛️

Symfony est un framework PHP professionnel pour créer des applications web robustes et évolutives.

Analogie : La cuisine vs le restaurant 🍳

PHP pur (sans framework) :

C'est comme cuisiner chez soi. Tu as tous les ingrédients (fonctions PHP), mais tu dois TOUT faire toi-même : préparer, cuire, dresser l'assiette, faire la vaisselle. C'est long et fatiguant.

Symfony (framework) :

C'est comme travailler dans un restaurant étoilé bien organisé. Tu as une cuisine équipée, des ustensiles de qualité, des recettes éprouvées, et une équipe qui gère les tâches répétitives. Tu te concentres sur l'essentiel : créer de bons plats !

En résumé : Symfony te fournit des outils, des structures et des bonnes pratiques pour que tu ne réinventes pas la roue. Tu codes plus vite, mieux et de manière plus sûre.

Pourquoi utiliser Symfony ? 💪

Avantage Explication
🏗️ Structure claire MVC (Modèle-Vue-Contrôleur) : code organisé et maintenable
⚡ Gain de temps Composants prêts à l'emploi (routing, formulaires, sécurité...)
🔒 Sécurité Protection contre XSS, CSRF, injections SQL par défaut
📚 Documentation Documentation complète et communauté active
🧩 Réutilisable Bundles et composants réutilisables
💼 Professionnel Utilisé par de grandes entreprises (BlaBlaCar, Spotify...)

Symfony vs PHP pur 🆚

❌ PHP pur (sans framework)

<?php
// Route manuelle
if ($_GET['page'] == 'home') {
    // Code home
}

// Requête BDD manuelle
$conn = mysqli_connect(...);
$result = mysqli_query($conn, 
    "SELECT * FROM users");

// Template manuel
echo "<h1>Titre</h1>";

// Sécurité manuelle
$input = htmlspecialchars($_POST['data']);
?>

😓 Beaucoup de code répétitif

✅ Avec Symfony

<?php
// Route automatique
#[Route('/home', name: 'home')]

// ORM Doctrine
$users = $userRepository->findAll();

// Template Twig
return $this->render('home.html.twig');

// Sécurité intégrée
// CSRF, XSS, etc. gérés automatiquement
?>

😎 Code propre et sécurisé

# 💾 Partie 1

Installation et Configuration

Mettre en place votre environnement

Prérequis 📋

Avant d'installer Symfony, vous avez besoin de :

Outil Version minimum Pourquoi ?
PHP 8.1+ Le langage de base
Composer 2.0+ Gestionnaire de dépendances PHP
Symfony CLI Dernière Outil en ligne de commande (optionnel mais recommandé)

Vérifier vos versions

# Vérifier PHP
php -v

# Vérifier Composer
composer -V

# Vérifier Symfony CLI
symfony -V

Installer Composer 📦

Composer est le gestionnaire de paquets de PHP (comme npm pour JavaScript).

Analogie : Le bibliothécaire 📚

Imagine que tu veux lire 50 livres pour un projet. Au lieu d'aller les chercher toi-même dans toute la bibliothèque, tu demandes au bibliothécaire (Composer) : "J'ai besoin de ces livres". Il va les chercher pour toi, les organise, et s'assure que tu as les bonnes versions !

Installation sur Windows

# Télécharger depuis https://getcomposer.org/
# Installer Composer-Setup.exe
# Redémarrer le terminal

Installation sur Mac/Linux

# Via le script officiel
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer

Créer un projet Symfony 🚀

Il existe 2 façons de créer un projet Symfony :

1️⃣ Avec Composer (classique)

# Application web complète
composer create-project \
  symfony/skeleton mon-projet

cd mon-projet

2️⃣ Avec Symfony CLI (recommandé)

# Plus rapide et moderne
symfony new mon-projet

cd mon-projet

Que se passe-t-il pendant l'installation ?

  1. Téléchargement des fichiers
    Composer télécharge Symfony et ses dépendances
  2. Création de la structure
    Les dossiers (src/, config/, public/...) sont créés
  3. Configuration initiale
    Les fichiers de config de base sont générés
  4. Installation des dépendances
    Les composants essentiels sont installés

Démarrer le serveur de développement 🌐

Symfony inclut un serveur web de développement intégré.

Avec Symfony CLI (recommandé)

# Démarrer le serveur
symfony serve

# Le serveur démarre sur https://127.0.0.1:8000
# Ou http://localhost:8000

Avec PHP (alternatif)

# Démarrer avec PHP built-in server
php -S localhost:8000 -t public/

✅ Ça marche ! Si tu vois la page d'accueil Symfony dans ton navigateur, ton installation est réussie !

🌐 Ouvre ton navigateur
↓
Va sur http://localhost:8000
↓
Tu vois la page "Welcome to Symfony" ? 🎉
↓
BRAVO ! Symfony fonctionne !
# 📁 Partie 2

Structure d'un projet Symfony

Comprendre l'organisation des fichiers

L'arborescence complète 🌳

mon-projet/
├── bin/                  # Scripts exécutables
│   └── console          # Console Symfony (commandes)
├── config/              # 📋 Configuration de l'app
│   ├── packages/        # Config des bundles
│   ├── routes.yaml      # Définition des routes
│   └── services.yaml    # Services et dépendances
├── public/              # 🌐 Racine web publique
│   └── index.php        # Point d'entrée de l'app
├── src/                 # 💻 TON CODE ICI !
│   ├── Controller/      # Contrôleurs
│   ├── Entity/          # Entités (modèles)
│   └── Repository/      # Accès base de données
├── templates/           # 🎨 Vues Twig
├── var/                 # Fichiers temporaires
│   ├── cache/           # Cache
│   └── log/             # Logs
├── vendor/              # 📦 Dépendances (ne pas modifier)
├── .env                 # Variables d'environnement
└── composer.json        # Dépendances du projet

Les dossiers expliqués en détail 📁

📂 src/ - Votre code

C'est ici que VOUS allez travailler !

Analogie : C'est votre bureau personnel. Tout ce que vous créez va ici.

📂 config/ - Configuration

Fichiers de configuration de l'application.

Analogie : Les réglages de votre voiture (vitesse max, type d'essence, etc.)

📂 public/ - Fichiers publics

Seul dossier accessible depuis Internet. Contient CSS, JS, images et index.php.

Analogie : La vitrine de votre magasin. C'est ce que les clients voient.

📂 templates/ - Vues HTML

Vos fichiers Twig (HTML avec des super-pouvoirs).

Analogie : Les moules à gâteaux. Ils définissent la forme de vos pages.

public/index.php - Le point d'entrée unique 🚪

TOUTES les requêtes passent par ce fichier unique !

Analogie : Le standard téléphonique 📞

Dans une grande entreprise, quand tu appelles, tu tombes d'abord sur le standard. Le standardiste (index.php) écoute ta demande, puis te redirige vers la bonne personne (contrôleur).

Tu n'appelles JAMAIS directement un employé. Toujours le standard d'abord !

Flux d'une requête

1. Utilisateur → http://localhost:8000/contact
2. Serveur web → appelle public/index.php
3. index.php → charge Symfony
4. Symfony → lit /contact dans le routing
5. Routing → appelle le bon contrôleur
6. Contrôleur → génère la réponse
7. Réponse → envoyée à l'utilisateur

C'est le Front Controller Pattern : Un seul point d'entrée pour toute l'application = plus facile à sécuriser et à gérer !

# 🛣️ Partie 3

Le système de Routing

Relier les URLs aux contrôleurs

C'est quoi le routing ? 🛣️

Le routing associe une URL à un contrôleur (fonction PHP).

Analogie : Le GPS de l'application 🗺️

Imagine que ton application est une ville :

Sans routing = conducteur perdu. Avec routing = destination atteinte !

Exemple simple

URL : /contact
↓
Routing : "Ah, /contact c'est ContactController"
↓
Contrôleur exécuté
↓
Page affichée

Créer une route (méthode moderne) 🎯

Depuis Symfony 6, on utilise les attributs PHP pour définir les routes.

Exemple complet

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class HomeController extends AbstractController
{
    #[Route('/', name: 'home')]
    public function index(): Response
    {
        return new Response('Bienvenue sur mon site !');
    }
}

Décomposition ligne par ligne

  1. #[Route('/', name: 'home')]
    C'est l'attribut de route. Il dit : "Quand on accède à /, exécute la fonction en dessous"
  2. '/'
    L'URL (ici la racine du site)
  3. name: 'home'
    Le nom de la route (pour la retrouver facilement)
  4. public function index()
    La fonction qui sera exécutée
  5. return new Response(...)
    On retourne une réponse HTTP

Routes avec paramètres 📝

On peut capturer des valeurs dynamiques dans l'URL !

Exemple : Page utilisateur

<?php
#[Route('/user/{id}', name: 'user_show')]
public function show(int $id): Response
{
    return new Response("Affichage de l'utilisateur n°" . $id);
}

// URL : /user/123
// Affiche : Affichage de l'utilisateur n°123

Comment ça marche ?

/user/{id} ← Template de l'URL
↑
Partie dynamique

Quand tu vas sur /user/123 :
→ Symfony extrait "123"
→ L'injecte dans le paramètre $id
→ Ta fonction reçoit $id = 123

Avec plusieurs paramètres

#[Route('/blog/{category}/{slug}', name: 'blog_post')]
public function post(string $category, string $slug): Response
{
    return new Response(
        "Catégorie: $category, Article: $slug"
    );
}

// URL : /blog/tech/symfony-tutorial
// Affiche : Catégorie: tech, Article: symfony-tutorial

Contraintes sur les paramètres 🔒

On peut forcer un paramètre à respecter un format !

Exemple : ID doit être un nombre

#[Route('/user/{id}', name: 'user_show', requirements: ['id' => '\d+'])]
public function show(int $id): Response
{
    // $id sera TOUJOURS un nombre
}

// ✅ /user/123 → Fonctionne
// ❌ /user/abc → Erreur 404

Contraintes courantes

Contrainte Regex Exemple
Nombres uniquement \d+ 123, 456
Lettres uniquement [a-zA-Z]+ hello, World
Slug (URL friendly) [a-z0-9-]+ mon-article-123
Format date \d{4}-\d{2}-\d{2} 2026-01-28
# 🎮 Partie 4

Les Contrôleurs

Le cerveau de votre application

C'est quoi un contrôleur ? 🎮

Un contrôleur est une classe PHP qui contient la logique métier de votre application.

Analogie : Le chef d'orchestre 🎼

Dans un orchestre :

Le chef lit la partition, dit aux musiciens quoi jouer et quand, puis coordonne le tout pour créer la symphonie (réponse HTTP).

Rôle d'un contrôleur

  1. Recevoir la requête
    Récupère les données de l'URL, du formulaire, etc.
  2. Traiter
    Appelle des services, interroge la BDD, effectue des calculs
  3. Retourner une réponse
    Génère du HTML, JSON, PDF, etc.

Créer un contrôleur 🏗️

Avec la console Symfony (recommandé)

php bin/console make:controller HomeController

Cette commande crée automatiquement :

Code généré

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class HomeController extends AbstractController
{
    #[Route('/home', name: 'app_home')]
    public function index(): Response
    {
        return $this->render('home/index.html.twig', [
            'controller_name' => 'HomeController',
        ]);
    }
}

Types de réponses possibles 📤

1. Réponse texte simple

return new Response('Hello World!');

2. Réponse HTML (template Twig)

return $this->render('home/index.html.twig', [
    'titre' => 'Ma page d\'accueil',
    'date' => new DateTime()
]);

3. Réponse JSON (pour API)

return $this->json([
    'message' => 'Success',
    'data' => ['id' => 123, 'name' => 'Marie']
]);

4. Redirection

// Redirection vers une URL
return $this->redirectToRoute('home');

// Redirection vers une URL externe
return $this->redirect('https://google.com');

5. Fichier à télécharger

return $this->file('/path/to/document.pdf');

Récupérer les données de la requête 📥

Symfony injecte automatiquement l'objet Request !

Paramètres GET

use Symfony\Component\HttpFoundation\Request;

#[Route('/search', name: 'search')]
public function search(Request $request): Response
{
    // URL: /search?q=symfony
    $query = $request->query->get('q');
    
    return new Response("Recherche pour: " . $query);
}

Paramètres POST (formulaire)

#[Route('/login', name: 'login', methods: ['POST'])]
public function login(Request $request): Response
{
    $email = $request->request->get('email');
    $password = $request->request->get('password');
    
    // Traiter le login...
}

Headers HTTP

$userAgent = $request->headers->get('User-Agent');
$acceptLanguage = $request->headers->get('Accept-Language');
# 🎨 Partie 5

Templates Twig

Générer du HTML dynamique

C'est quoi Twig ? 🎨

Twig est le moteur de templates de Symfony. Il permet de générer du HTML de manière élégante et sécurisée.

Analogie : Les pochoirs 🖌️

Imagine que tu veux peindre 100 fois le même logo sur des T-shirts :

Sans pochoir (PHP pur) : Tu dessines à la main chaque fois. Long, fatiguant, et jamais identique.

Avec pochoir (Twig) : Tu crées un pochoir une fois, puis tu l'appliques partout. Rapide, propre, et toujours parfait !

❌ PHP dans le HTML

<h1><?php echo htmlspecialchars($titre); ?></h1>
<?php foreach($users as $user): ?>
    <p><?php echo $user['name']; ?></p>
<?php endforeach; ?>

😓 Moche et verbeux

✅ Twig

<h1>{{ titre }}</h1>
{% for user in users %}
    <p>{{ user.name }}</p>
{% endfor %}

😎 Propre et lisible

Syntaxe Twig de base 📝

Syntaxe Utilisation Exemple
{{ ... }} Afficher une variable {{ nom }}
{% ... %} Instructions (if, for...) {% if age > 18 %}
{# ... #} Commentaire {# Ceci est un commentaire #}

Exemples d'utilisation

{# Afficher une variable #}
<h1>Bonjour {{ prenom }} !</h1>

{# Condition #}
{% if age >= 18 %}
    <p>Vous êtes majeur</p>
{% else %}
    <p>Vous êtes mineur</p>
{% endif %}

{# Boucle #}
<ul>
{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

Passer des variables au template 📦

Dans le contrôleur, on passe un tableau de variables :

Contrôleur

#[Route('/blog', name: 'blog')]
public function blog(): Response
{
    $articles = [
        ['titre' => 'Article 1', 'auteur' => 'Marie'],
        ['titre' => 'Article 2', 'auteur' => 'Paul'],
        ['titre' => 'Article 3', 'auteur' => 'Sophie']
    ];
    
    return $this->render('blog/index.html.twig', [
        'articles' => $articles,
        'siteName' => 'Mon Blog',
        'year' => 2025
    ]);
}

Template (blog/index.html.twig)

<h1>{{ siteName }}</h1>

{% for article in articles %}
    <article>
        <h2>{{ article.titre }}</h2>
        <p>Par {{ article.auteur }}</p>
    </article>
{% endfor %}

<footer>
    <p>© {{ year }} {{ siteName }}</p>
</footer>

Héritage de templates 🧬

Créer un layout de base et le réutiliser !

Analogie : Le moule à gaufres 🧇

Tu as un moule à gaufres (layout de base) avec des trous (blocks). Pour chaque gaufre (page), tu remplis les trous avec ta pâte (contenu spécifique). Le moule reste le même, mais chaque gaufre est unique !

1. Créer le layout de base (templates/base.html.twig)

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Mon Site{% endblock %}</title>
</head>
<body>
    <header>
        <h1>Mon Super Site</h1>
        <nav>...</nav>
    </header>
    
    <main>
        {% block content %}{% endblock %}
    </main>
    
    <footer>
        <p>© 2025 Mon Site</p>
    </footer>
</body>
</html>

2. Étendre le layout (templates/blog/index.html.twig)

{% extends 'base.html.twig' %}

{% block title %}Mon Blog{% endblock %}

{% block content %}
    <h2>Bienvenue sur mon blog !</h2>
    {% for article in articles %}
        <article>{{ article.titre }}</article>
    {% endfor %}
{% endblock %}

Filtres Twig 🔧

Les filtres transforment les variables avant affichage.

Filtres courants

Filtre Utilisation Exemple
upper Majuscules {{ nom|upper }} → MARIE
lower Minuscules {{ nom|lower }} → marie
length Longueur {{ texte|length }} → 15
date Formater date {{ date|date('d/m/Y') }}
slice Extraire partie {{ texte|slice(0, 10) }}
default Valeur par défaut {{ nom|default('Anonyme') }}

Chaîner les filtres

{{ description|striptags|slice(0, 100)|upper }}

Étapes :
1. striptags → retire les balises HTML
2. slice(0, 100) → garde 100 premiers caractères
3. upper → convertit en majuscules
# ⌨️ Partie 6

La Console Symfony

Votre outil en ligne de commande

C'est quoi la console Symfony ? ⌨️

La console est un outil en ligne de commande pour gérer votre application.

Analogie : La boîte à outils du mécanicien 🔧

Un mécanicien a une boîte à outils avec des clés, tournevis, pinces... Chaque outil fait une tâche précise. La console Symfony, c'est pareil ! Des commandes pour chaque besoin : créer un contrôleur, vider le cache, lancer les tests, etc.

Comment utiliser la console ?

# Format général
php bin/console nom:commande [options] [arguments]

# Exemple
php bin/console make:controller HomeController

Commandes essentielles 🛠️

Commande Action
php bin/console list Liste toutes les commandes disponibles
php bin/console about Informations sur l'application
php bin/console cache:clear Vider le cache
php bin/console debug:router Lister toutes les routes
php bin/console make:controller Créer un contrôleur
php bin/console make:entity Créer une entité
php bin/console doctrine:migrations:migrate Exécuter les migrations BDD

Aide sur une commande

php bin/console help make:controller

# Affiche :
# - Description de la commande
# - Options disponibles
# - Exemples d'utilisation

debug:router - Voir toutes vos routes 🗺️

Cette commande liste toutes les routes de votre application.

Utilisation

php bin/console debug:router

Résultat

 Name        Method   Path            Controller
-----------------------------------------------------
 home        ANY      /               App\Controller\HomeController::index
 blog        GET      /blog           App\Controller\BlogController::index
 blog_show   GET      /blog/{id}      App\Controller\BlogController::show
 contact     ANY      /contact        App\Controller\ContactController::index

Chercher une route spécifique

php bin/console debug:router blog

# Affiche uniquement la route "blog" avec tous ses détails
# 💡 Partie 7

Exemples Pratiques

Mettre en pratique

Exemple 1 : Page d'accueil simple 🏠

1. Créer le contrôleur

php bin/console make:controller HomeController

2. Modifier le contrôleur (src/Controller/HomeController.php)

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class HomeController extends AbstractController
{
    #[Route('/', name: 'home')]
    public function index(): Response
    {
        return $this->render('home/index.html.twig', [
            'siteName' => 'Mon Super Site',
            'year' => date('Y')
        ]);
    }
}

3. Créer le template (templates/home/index.html.twig)

{% extends 'base.html.twig' %}

{% block title %}Accueil - {{ siteName }}{% endblock %}

{% block body %}
    <h1>Bienvenue sur {{ siteName }} !</h1>
    <p>Ceci est ma première page Symfony.</p>
    
    <footer>
        <p>© {{ year }} {{ siteName }}</p>
    </footer>
{% endblock %}

Exemple 2 : Liste d'articles de blog 📰

Contrôleur (src/Controller/BlogController.php)

<?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: 'blog_index')]
    public function index(): Response
    {
        // En vrai, ces données viendraient de la base de données
        $articles = [
            [
                'id' => 1,
                'titre' => 'Découvrir Symfony',
                'auteur' => 'Marie Dupont',
                'date' => new \DateTime('2025-01-15'),
                'resume' => 'Introduction au framework Symfony...'
            ],
            [
                'id' => 2,
                'titre' => 'Les bases de Twig',
                'auteur' => 'Paul Martin',
                'date' => new \DateTime('2025-01-20'),
                'resume' => 'Apprendre à utiliser Twig...'
            ],
            [
                'id' => 3,
                'titre' => 'Doctrine ORM',
                'auteur' => 'Sophie Bernard',
                'date' => new \DateTime('2025-01-25'),
                'resume' => 'Gérer vos bases de données...'
            ]
        ];
        
        return $this->render('blog/index.html.twig', [
            'articles' => $articles
        ]);
    }
    
    #[Route('/blog/{id}', name: 'blog_show', requirements: ['id' => '\d+'])]
    public function show(int $id): Response
    {
        // En vrai, on récupérerait l'article depuis la BDD
        return $this->render('blog/show.html.twig', [
            'articleId' => $id
        ]);
    }
}

Template liste (templates/blog/index.html.twig)

{% extends 'base.html.twig' %}

{% block title %}Blog{% endblock %}

{% block body %}
    <h1>Articles du Blog</h1>
    
    <div class="articles">
        {% for article in articles %}
            <article>
                <h2>
                    <a href="{{ path('blog_show', {id: article.id}) }}">
                        {{ article.titre }}
                    </a>
                </h2>
                <p class="meta">
                    Par {{ article.auteur }} 
                    le {{ article.date|date('d/m/Y') }}
                </p>
                <p>{{ article.resume }}</p>
            </article>
        {% else %}
            <p>Aucun article pour le moment.</p>
        {% endfor %}
    </div>
{% endblock %}

Exemple 3 : Formulaire de contact 📧

Contrôleur

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class ContactController extends AbstractController
{
    #[Route('/contact', name: 'contact')]
    public function index(Request $request): Response
    {
        $message = null;
        
        // Si le formulaire a été soumis
        if ($request->isMethod('POST')) {
            $nom = $request->request->get('nom');
            $email = $request->request->get('email');
            $sujet = $request->request->get('sujet');
            $texte = $request->request->get('message');
            
            // En vrai, on enverrait un email ici
            $message = "Merci $nom, votre message a été envoyé !";
        }
        
        return $this->render('contact/index.html.twig', [
            'message' => $message
        ]);
    }
}

Template (templates/contact/index.html.twig)

{% extends 'base.html.twig' %}

{% block title %}Contact{% endblock %}

{% block body %}
    <h1>Contactez-nous</h1>
    
    {% if message %}
        <div class="alert success">{{ message }}</div>
    {% endif %}
    
    <form method="POST">
        <div>
            <label>Nom :</label>
            <input type="text" name="nom" required>
        </div>
        
        <div>
            <label>Email :</label>
            <input type="email" name="email" required>
        </div>
        
        <div>
            <label>Sujet :</label>
            <input type="text" name="sujet" required>
        </div>
        
        <div>
            <label>Message :</label>
            <textarea name="message" required></textarea>
        </div>
        
        <button type="submit">Envoyer</button>
    </form>
{% endblock %}

Flux complet d'une requête Symfony 🌊

Récapitulons le parcours complet d'une requête HTTP dans Symfony :

  1. L'utilisateur clique sur un lien
    Exemple : http://localhost:8000/blog/5
  2. Le serveur web reçoit la requête
    Apache/Nginx redirige vers public/index.php
  3. index.php charge Symfony
    Le framework démarre et initialise tous ses composants
  4. Le Router analyse l'URL
    Il cherche quelle route correspond à /blog/5
  5. Le Router trouve la route
    Route: /blog/{id} → BlogController::show()
  6. Le Contrôleur est exécuté
    BlogController::show(5) s'exécute avec id=5
  7. Le Contrôleur traite
    Récupère les données, fait les calculs nécessaires
  8. Le Template est rendu
    Twig génère le HTML avec les données
  9. La Response est retournée
    Le HTML est envoyé au navigateur de l'utilisateur
  10. Le navigateur affiche la page
    L'utilisateur voit la page !
Utilisateur → URL
↓
Serveur Web → public/index.php
↓
Symfony → Kernel
↓
Router → Analyse l'URL
↓
Contrôleur → Logique métier
↓
Twig → Génération HTML
↓
Response → Envoi au navigateur
↓
Utilisateur ← Page affichée ✅
# 🎓 Récapitulatif

Ce qu'on a appris

Résumé complet 📚

Concept Définition Commande/Syntaxe
Symfony Framework PHP professionnel composer create-project symfony/skeleton
Routing Associer URL → Contrôleur #[Route('/path', name: 'route_name')]
Contrôleur Logique de l'application php bin/console make:controller
Twig Moteur de templates {{ variable }}, {% for %}
Response Ce qui est renvoyé au client return new Response()
Console Outil en ligne de commande php bin/console list

Structure du projet - Rappel 📁

mon-projet/
├── 💻 src/ ← TON CODE (contrôleurs, entities...)
├── 🎨 templates/ ← Tes vues Twig
├── 📋 config/ ← Configuration
├── 🌐 public/ ← Fichiers publics (CSS, JS, images)
├── 📦 vendor/ ← Dépendances (ne pas toucher)
└── ⌨️ bin/console ← Commandes Symfony

Règle d'or : Tu travailles dans src/, templates/ et config/. Le reste, tu n'y touches pas (sauf public/ pour tes assets) !

Commandes à retenir 🛠️

Action Commande
Créer un projet symfony new mon-projet
Démarrer le serveur symfony serve
Créer un contrôleur php bin/console make:controller NomController
Lister les routes php bin/console debug:router
Vider le cache php bin/console cache:clear
Lister les commandes php bin/console list

Bonnes pratiques 💡

  1. Utilise toujours les attributs pour les routes
    C'est plus moderne et plus lisible que YAML
  2. Un contrôleur = une responsabilité
    Ne mets pas tout dans HomeController
  3. Hérite toujours de AbstractController
    Tu bénéficies des méthodes utiles (render, json...)
  4. Utilise Twig pour TOUT le HTML
    Ne mélange jamais PHP et HTML directement
  5. Nomme tes routes
    Toujours mettre name: 'route_name'
  6. Utilise la console
    make:controller, make:entity... gagnent du temps
  7. Vide le cache si ça bug
    php bin/console cache:clear résout souvent les problèmes

Prochaines étapes 🚀

Maintenant que tu connais les bases, voici ce qu'il faut apprendre ensuite :

Étape Sujet Pourquoi ?
1 Doctrine ORM Gérer la base de données
2 Formulaires Symfony Créer et valider des formulaires
3 Sécurité Authentification et autorisations
4 Services Injection de dépendances
5 API REST Créer des APIs modernes

Ressources utiles 📖

Documentation officielle

🌐 https://symfony.com/doc

La doc officielle est EXCELLENTE. Utilise-la !

SymfonyCasts

🎬 https://symfonycasts.com

Tutoriels vidéo de qualité (certains gratuits)

Communauté

💬 Symfony Slack

Communauté active et bienveillante

💡 Astuce : La documentation Symfony est régulièrement mise à jour et très bien écrite. En cas de doute, c'est ta meilleure amie !

Erreurs courantes (et comment les éviter) ⚠️

❌ Erreur 1 : "No route found"

Cause : Tu as oublié l'attribut #[Route] ou mal écrit l'URL

Solution : Vérifie avec php bin/console debug:router

❌ Erreur 2 : "Unable to find template"

Cause : Le fichier Twig n'existe pas ou mal orthographié

Solution : Vérifie le chemin dans templates/

❌ Erreur 3 : Page blanche

Cause : Erreur PHP cachée par le cache

Solution : php bin/console cache:clear et regarde les logs dans var/log/

❌ Erreur 4 : "Class not found"

Cause : Mauvais namespace ou classe mal orthographiée

Solution : Vérifie le namespace et le nom de la classe

Exercices pratiques 💪

Pour bien assimiler, voici des exercices à faire :

Exercice 1 : Portfolio personnel

Crée un site avec :

Utilise un layout de base et Twig pour toutes les pages.

Exercice 2 : Blog simple

Crée un blog avec :

Exercice 3 : Calculatrice

Crée une calculatrice avec :

🎓 Bravo !

Tu as terminé l'introduction à Symfony

Tu sais maintenant :

✅ Installer et configurer Symfony

✅ Comprendre la structure d'un projet

✅ Créer des routes et des contrôleurs

✅ Utiliser Twig pour les templates

✅ Utiliser la console Symfony

Continue à pratiquer ! 💪

Formation DWWM - 2026