Cheatsheet : Symfony
Symfony : l'essentiel pour votre apprentissage dans une cheatsheet signée laConsole.
Création d'un projet
# Projet avec structure de base (API, Console, Services...)
symfony new nom_projet
# Projet avec paquets élémentaires pour une app/site web
symfony new nom_projet --webapp
# Projet CRUD de démo pour prise en main du framework
symfony new nom_projet --demo
--version
pour installer une version spécifique (ex:--version=5.4
)symfony console check:requirements
=> check si système OK pour dev en Symfony
Démarrer/arrêter le serveur
# Démarrage du serveur (ou symfony serve)
symfony server:start
# Arrêt du serveur
symfony server:stop
-d
pour démarrer le serveur en tâche de fond
Base de données
# Créer la BDD (ou symfony console d:d:c)
symfony console doctrine:database:create
# Supprimer la BDD (ou symfony console d:d:d)
symfony console doctrine:database:drop
Selon adresse spécifiée dans DATABASE_URL
du 📄 .env
Migrations
Mise à jour de la structure de BDD selon modèle objet de l’app.
# Créer une migration
symfony console make:migration
# Exécuter les migrations non exécutées
symfony console doctrine:migrations:migrate
# Afficher l'état des migrations
symfony console doctrine:migrations:status
# Exécuter une migration spécifique
symfony console doctrine:migrations:execute --up <version_migration>
# Annuler une migration spécifique
symfony console doctrine:migrations:execute --down <version_migration>
Créer un contrôleur
symfony console make:controller
Créer une entité
symfony console make:entity
Créer un formulaire (Form Type)
symfony console make:form
Déclarer une route
// Route statique
#[Route('/blog', name: 'app_blog_index')]
public function index() { ... }
// Route dynamique
#[Route('/blog/{slug}', name: 'app_blog_show')]
public function show(string $slug) {
// $slug => valeur du paramètre de route
}
Préfixe de route
#[Route('/admin')]
class AdminController {
// path => /admin/user
#[Route('/user', name: '...')]
}
Options de routes
// Check validité d'un paramètre de route (via regex)
#[Route(... requirements: ['nom_param' => '[a-z0-9-]+'])]
// Valeur par défaut pour un paramètre de route
#[Route(... defaults: ['nom_param' => 'valeur'])]
// Route restreinte à certaines méthodes HTTP
#[Route(... methods: ['GET', 'POST'])]
Analyser la requête
use Symfony\Component\HttpFoundation\Request;
// ...
public function maMethode(Request $request): Response {
// Equivalent pour $_GET['param1']
$request->query->get('param1');
// Equivalent pour $_POST['param2']
$request->request->get('param2');
// Connaître la méthode HTTP de la requête
$request->isMethod('MA_METHODE'); // GET, POST...
}
Retourner un template
// Sans données
return $this->render('chemin/vers/template.html.twig');
// Avec données
return $this->render(
'chemin/vers/template.html.twig', [
'donnee_pour_template' => $maDonnee
]
);
render()
pointe automatiquement vers 📂 templates
Redirection
// Vers route statique
return $this->redirectToRoute('nom_route');
// Vers route dynamique
return $this->redirectToRoute(
'nom_route', [
'param1' => 'valeur1',
'param2' => 'valeur2'
]
);
Variables TWIG
{{ ma_variable }}
{{ mon_tableau[0] }}, {{ mon_tableau['cle'] }} ou {{ mon_tableau.cle }}
{{ mon_objet.propriete }}
{% set a = ... %}
=> déclarer une variable locale au template- Dans
📄 config/packages/twig.yaml
=> variables globales custom - Variable globale
app
disponible (app.user
,app.session
…)
Filtres TWIG
Fonctions permettant de manipuler et de formater des données.
{# Sans paramètre #}
{{ ma_variable|length }}
{# Avec paramètre #}
{{ ma_variable|date('d/m/Y') }}
{{ ma_variable|replace({'06': '+33'}) }}
{# Filtres combinés #}
{{ ma_variable|upper|slice(0, 1) }}
Des filtres combinés s’exécutent dans l’ordre
Héritage TWIG
Réutilisation et extension de modèles de manière hiérarchique.
{# base.html.twig (parent) #}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
{% block title %}Welcome!{% endblock %}
</title>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
{# ma_page.html.twig (enfant) #}
{% extends 'base.html.twig' %}
{% block title %}Hello{% endblock %}
{% block body %}
<h1>Ma page</h1>
{% endblock %}
- Parent définit des blocs / l’enfant y insère du contenu
- Héritage =>
extends
dans le template l’enfant parent()
injecte dans l’enfant le contenu du bloc parent
Inclusion TWIG
Inclusion d’un template dans un autre.
{{ include '_header.html.twig' }}
{# Avec transmission de variables #}
{{ include '_header.html.twig' with { 'foo': 'bar' } }}
- Préfixer templates à inclure d’un
_
(ex:_header.html.twig
) include()
pointe automatiquement vers📂 templates
Liens entre pages
<a href="{{ path('nom_route') }}">
Lien vers page statique
</a>
<a href="{{ path('nom_route', { param1: 'valeur' }) }}">
Lien vers page dynamique
</a>
Boucles TWIG
Boucler sur des données.
{% for item in items %}
...
{# Ici, variable "loop" exploitable #}
{% else %}
{# Si le tableau "items" est vide... #}
{% endfor %}
loop.index
: indice de l’itération couranteloop.length
: nombre d’itérations totalesloop.first
: s’il s’agit de la 1ère itérationloop.last
: s’il s’agit de la dernière itération
Conditions TWIG
Conditionner l’affichage de balises.
{% if ma_variable == 1 %}
...
{% elseif ma_variable == 2 %}
...
{% else %}
...
{% endif %}
Lier des ressources statiques (CSS, JS, médias...)
{# Logo situé dans "public/img/logo.png" #}
<img src="{{ asset('img/logo.png') }}" alt="...">
{# Fichier CSS situé dans "public/css/app.css" #}
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
{# Fichier JS situé dans "public/js/app.js" #}
<script src="{{ asset('js/app.js') }}"></script>
asset()
pointe automatiquement vers 📂 public
Afficher un formulaire
{# Affichage brut #}
form(monForm)
{# Affichage sur-mesure (contrôle sur le balisage) #}
{{ form_start(monForm) }}
{# Champ personnalisé #}
<div class="form-item">
{{ form_label(monForm.field1) }}
{{ form_widget(monForm.field1) }}
<span class="form-help">
{{ form_help(monForm.field1) }}
</span>
<div class="form-error">
{{ form_errors(monForm.field1) }}
</div>
</div>
{# Champ non personnalisé #}
{{ form_row(monForm.field2) }}
{{ form_end(monForm) }}
- Dans
📄 config/packages/twig.yaml
=> customisation avec un thème form_end(monForm, {'render_rest': false})
=> n’affiche pas les champs omis
Connexion à la BDD (.env)
{# MySQL #}
DATABASE_URL="mysql://username:[email protected]:3306/db_name?serverVersion=X.Y.Z&charset=utf8mb4"
{# MariaDB #}
DATABASE_URL="mysql://username:[email protected]:3307/db_name?serverVersion=X.Y.Z-MariaDB&charset=utf8mb4"
{# PostgreSQL #}
DATABASE_URL="postgresql://username:[email protected]:5432/db_name?serverVersion=X.Y.Z&charset=utf8"
username
: nom d’utilisateur SGBDpassword
: mot de passe SGBD127.0.0.1:3306
: adresse BDD (3306
=> MySQL /3307
=> MariaDB /5432
=> PostgreSQL)db_name
: nom de la BDDserverVersion
: taperSHOW GLOBAL VARIABLES LIKE '%version%'
dans SGBD
Récupération (READ)
#[Route(
'/entite',
name: 'app_entite_list',
methods: ['GET']
)]
public function list(
Request $request,
EntityManagerInterface $em
): Response {
$repository = $em->getRepository(Entite::class);
$objets = $repository->findAll();
return $this->render('...', [
'objets' => $objets
]);
}
#[Route(
'/entite/{id}',
name: 'app_entite_show',
methods: ['GET']
)]
public function show(
Request $request,
EntityManagerInterface $em,
int $id
): Response {
$repository = $em->getRepository(Entite::class);
$objet = $repository->find($id);
return $this->render('...', [
'objet' => $objet
]);
}
Ne pas oublier de use
les classes
Enregistrement (CREATE)
#[Route(
'/entite/ajouter',
name: 'app_entite_add',
methods: ['GET', 'POST']
)]
public function create(
Request $request,
EntityManagerInterface $em
): Response {
$objet = new Entite();
$form = $this->createForm(Entite::class, $objet);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($objet);
$em->flush();
return $this->redirectToRoute('...');
}
return $this->render('...', [
'form' => $form
]);
}
Ne pas oublier de use
les classes
Modification (UPDATE)
#[Route(
'/entite/{id}/modifier',
name: 'app_entite_edit',
methods: ['GET', 'POST']
)]
public function update(
Request $request,
EntityManagerInterface $em,
int $id
): Response {
$repository = $em->getRepository(Entite::class);
$objet = $repository->find($id);
$form = $this->createForm(Entite::class, $objet);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->flush();
return $this->redirectToRoute('...');
}
return $this->render('...', [
'form' => $form
]);
}
Ne pas oublier de use
les classes
Suppression (DELETE)
#[Route(
'/entite/{id}/supprimer',
name: 'app_entite_delete',
methods: ['POST']
)]
public function delete(
Request $request,
EntityManagerInterface $em,
int $id
): Response {
$repository = $em->getRepository(Entite::class);
$objet = $repository->find($id);
$em->remove($objet);
$em->flush();
return $this->redirectToRoute('...');
}
Ne pas oublier de use
les classes