Objectif général
Prendre en main l’un des frameworks PHP les plus utilisés
Objectifs opérationnels :
Faire correspondre une URL donnée à un traitement précis grâce au routage
Traiter les requêtes grâce aux contrôleurs
Intégrer des données dans des templates grâce à TWIG
Faciliter la communication avec une base de données grâce à Doctrine
Permettre à un utilisateur d’initialiser ou de modifier les attributs d'un objet métier grâce aux formulaires
3. Objectifs opérationnels
• Faire correspondre une URL donnée à un traitement précis
grâce au routage
• Traiter les requêtes grâce aux contrôleurs
• Intégrer des données dans des templates grâce à TWIG
• Faciliter la communication avec une base de données grâce
à Doctrine
• Permettre à un utilisateur d’initialiser ou de modifier les
attributs d'un objet métier grâce aux formulaires
5. Préliminaires
sommaire
1) Qu’est ce qu’un Framework ?
2) Qu’est ce que Symfony ?
3) Prérequis pour installer Symfony
4) Installation de Symfony sous Windows avec Composer
5) Installation de Symfony sous Mac et Linux avec Composer
6) Première page
5
6. Préliminaires
Qu’est ce qu’un Framework ?
• Problématiques
Comment développer efficacement (rapidité, bonnes
pratiques, …) une application ?
• Solution : ensemble de composants et de préconisations
« prêt à l’emploi » = Framework
• Avantages d’un Framework
Structuration du code (modèle MVC)
Abstraction de la base de données
Réutilisation de composants éprouvés et approuvés
(Email, Users, …)
Instauration de bonnes pratiques de codage
Facilitation de la maintenance et de l’évolution du code
Facilitation du travail en équipe
Forte communauté (support et mises à jour) 6
7. Préliminaires
Qu’est ce que Symfony ?
• Symfony est un des Frameworks PHP les plus utilisés
• Edité en 2005 par la société française SensioLabs
• Dernière version stable (Novembre 2020) : 5.2.6
• Adopté par Dailymotion, OpenClassrooms, Drupal,
BlaBlaCar, …
• Concurrencé par Laravel, CodeIgniter, Zend Framework,
CakePHP, …
7
8. Préliminaires
prérequis pour installer Symfony
• Version de PHP ≥ 7.2.5
• Activer les extensions Ctype, iconv, JSON, PCRE, Session,
SImpleXML et Tokenizer
• Prérequis pour utiliser Doctrine :
Activer PDO
Installer le pilote PDO du serveur de bdd à utiliser.
Pour ce cours, installer Symfony CLI
https://symfony.com/download
8
9. Préliminaires
Installation de Symfony sous Windows avec Composer
• S’assurer qu’un exécutable php est accessible globalement : chemin
d’accès présent dans le PATH
• Télécharger (https://getcomposer.org/Composer-Setup.exe) et
exécuter Composer-Setup.exe
• Pour ce cours, installer Symfony CLI
https://symfony.com/download
• Créer un nouveau projet Symfony
symfony new symfony-classroom
• Démarrer le projet avec les commandes :
cd symfony-classroom/ puis symfony serve
• Accéder à la page d’accueil de Symfony à l’adresse
http://localhost:8000/
9
10. Préliminaires
Installation de Symfony sous Mac et Linux
• S’assurer qu’un exécutable php est accessible globalement
• Télécharger la dernière version du composer.phar
https://getcomposer.org/download/
• Rendre globale puis exécutable la commande composer
cp chemin/vers/composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer
• Pour ce cours, installer Symfony CLI
https://symfony.com/download
• Créer un nouveau projet Symfony
symfony new symfony-classroom
• Démarrer le projet avec les commandes :
cd symfony-classroom/ puis symfony serve
• Accéder à la page d’accueil de Symfony à l’adresse
http://localhost:8000/ 10
11. Préliminaires
première page
1) Installer le module « maker »
Cmd : composer require --dev symfony/maker-bundle
2) Installer le module « annotation »
Commande : composer require annotations
3) Créer le premier contrôleur
php bin/console make:controller FirstController
4) Après le démarrage du serveur, requêter
http://127.0.0.1:8000/first
11
13. Routage
présentation
• Pbl : comment accéder à notre application ?
• Sol : définir des routes
• Routage = faire correspondre une URL donnée à une page
précise.
• Intérêt : avoir de belles URL pour un bon référencement Web
et un confort des visiteurs
Ex : /read/intro-to-symfony au lieu de
index.php?article_id=57
• Définition d’une route = motif d’un path d’URL + action d’un
contrôleur 13
14. Routage
définition en annotation
• Emplacement
juste avant la définition d’une action d’un contrôleur
• Syntaxe
/**
* @Route("path d’URL", name="nomRoute")
*/
• Exemple
/**
* @Route("/first", name="first")
*/
14
15. Routage
définition en YAML
• Emplacement
dans un fichier de configuration route.yaml du dossier config
• Syntaxe (retrait = 4 espaces)
nomRoute:
path: path d’URL
controller: namespaceControllerNomController::nomAction
• Exemple
first:
path: first
defaults: AppControllerFirstController::first
15
16. Routage
paramètre de route
• Pb : peut-on se servir du chemin pour envoyer des données
• Sol : un segment variable du chemin
• Paramètre de route = portion variable du path
• Exemple : id d’une données à traiter
• Syntaxes d’ajout du paramètre
1) Suffixer {nomParametre} au path
2) Passer $nomParametre en paramètre à l’action du
contrôleur
16
17. Routage
paramètre de route - exemple
• Dans FirstController.php, définissez cette route accompagnée
de son action
17
• Requêtez les chemins
/hello/votrePrenom
/hello // transition
18. Routage
paramètre optionnel de route
Syntaxes d’ajout du paramètre optionnel
1) Suffixer {nomParametre} au path
2) Passer $nomParametre = valeurParDefaut en
paramètre à l’action du contrôleur
18
19. Routage
paramètre optionnel de route - exemple
• Initialisez à "world" le paramètre de l’action hello()
• Requêtez les chemins
/hello/VotrePrenom
/hello
19
20. Routage
génération d’URL
• La génération d’URL permet
d’éviter d’écrire manuellement les valeurs des href dans les
templates
lorsqu’une URL a changé, de modifier juste la définition de
la route
• Méthode generateURL() du contrôleur qui reçoit en
paramètre le nom de la route
• La méthode peut même recevoir éventuellement, en second
paramètre, un tableau contenant le paramètre à passer à l’URL
20
21. Routage
génération d’URL - exemple
1) À l’action index()
• commentez l’instruction return ;
• ajoutez les instructions suivantes :
$url = $this->generateUrl('hello', ["prenom"=>"Redirected User"]);
return $this->redirect($url);
2) Testez le chemin /first
21
23. Contrôleurs
présentation
• Contrôleur : classe qui regroupe des actions connexes
• Action : fonction ou méthode qui reçoit une requête, la traite
et retourne une réponse (texte, HTML, XML, JSON, image,
redirection, erreur 404, …)
• Pour simplifier certain traitement, le contrôleur peut hériter
de la classe AbstractController
• Exemple : FirstController
23
24. Contrôleurs
réception de contenu via GET
• GET : méthode HTTP d’envoi qui annexe toute donnée à l’URL
• Importer la classe Request
use SymfonyComponentHttpFoundationRequest;
• Passer en paramètre une instance de Request à l’action qui
doit recevoir le contenu via GET
• Syntaxe de réception
$request->query->get("nomDuContenu")
24
25. Contrôleurs
réception de contenu via GET - exemple
• Ajouter à FirstController.php
use SymfonyComponentHttpFoundationRequest;
• Ajouter à hello() le code en rouge
public function hello($prenom, Request $request) {
$nom = $request->query->get("nom");
return $this->json(['message' => "Hello $prenom $nom !",]);
}
• Requêter
http://localhost:8000/hello/Yero?nom=Sow
25
26. Contrôleurs
réception de contenu via POST
• POST : méthode HTTP d’envoi qui incorpore toute donnée
dans la requête HTTP
• Importer la classe Request
use SymfonyComponentHttpFoundationRequest;
• Passer en paramètre un objet Request à l’action qui doit
recevoir le contenu via POST
• Syntaxe de réception
$request->request->get("nomDuContenu")
26
27. Contrôleurs
réception de contenu via POST - exemple
• Ajouter à hello() le code en rouge
$age = $request->request->get("age");
return $this->json([
'message' => "Hello $prenom $nom ! Are you $age old ?",
]);
• Avec un client REST (ARC ou Postman), faire une requête telle
que :
Méthod = POST
URL = http://localhost:8000/hello/Yero?nom=Sow
Paramètre de formulaire : age=32
27
28. Contrôleurs
retourner du texte
• Importer la classe Response
use SymfonyComponentHttpFoundationResponse;
• Retourner une instance de Response initialisée avec le texte
à retourner
return new Response(chaineDeCaracteres);
28
29. Contrôleurs
retourner du texte - exemple
• Si ce ne pas encore fait, ajouter à FirstController.php
use SymfonyComponentHttpFoundationResponse;
• Dans hello() commenter les lignes commençant par $age et
par return, puis ajouter la ligne suivante
return new Response("Bonjour $prenom $nom");
• Requêter
http://localhost:8000/hello/Yero?nom=Sow
29
30. Contrôleurs
retourner un template
• Utilisez la méthode render() qui rend un template (à voir) et
place ce contenu dans un objet Response
• Syntaxe
return $this->render('first/index.html.twig', [
'controller_name' => 'FirstController',
]);
30
31. Moteur de template Twig
sommaire
1) Présentation
2) Installation et emplacement
3) Nommage
4) Expressions
5) Filtres
6) Structures conditionnelles
7) Structures itératives
8) Inclusion d’un template
9) Héritage d’un template
31
32. Moteur de template Twig
présentation
• Un système de templates gère la disposition générale des
éléments de l’interface ainsi que l’aspect visuel de cette
interface
• Moteur de template = programme qui permet d’intégrer des
données dynamiques dans un template
• Qlq intérêts
Séparation du traitement et de la présentation
PHP ne « sais pas » comment les données seront affichées
TWIG ne « sais pas » comment les données sont obtenues
Facilitation du travail en équipe car plus accessible pour les
web designers
Rapidité : utilisation d’un cache
Sécurisation des variables
32
33. Moteur de template Twig
installation, emplacement et nommage
• Installation TWIG
commande : composer require twig
• Emplacement des templates
dossier « template » créé automatiquement par l’installation
de Twig
• Nommage
nom des fichiers et des dossiers en snake case
33
34. Moteur de template Twig
expressions
• Syntaxe d’affichage d’une expression
{{ expression }}
• Exemples
Variable simple : {{ age }}
Élément d’un tableau ou champ d’un objet :
{{ user.prenom }}
34
35. Moteur de template Twig
filtres
• Filtre : outil de formatage d’une donnée
• Syntaxes d’utilisation
{{ var | filtre }}
{{ var | filtre1 | filtre2 }}
{{ var | filtre(arg) }}
{% filter filtre %} contenu assez consistant à filtrer {% endfilter
%}
• Quelques filtres
lower / upper / capitalize
date(format,timezone),
join(sep)
number_format(nbr_dec,dec_pt,th_sep)
replace(search,replace)
+ d’infos : https://twig.symfony.com/doc/3.x/filters/index.html
35
36. Moteur de template Twig
structures conditionnelles
• {% if bool_expr %}
contenu
{% endif %}
• {% if bool_expr %}
contenu
{% else %}
contenu alternatif
{% endif %}
• {% if bool_expr1 %}
contenu
{% elseif bool_expr2 %}
contenu alternatif
{% else %}
autre contenu
alternatif
{% endif %} 36
37. Moteur de template Twig
structures itératives
• {% for donnée in ensDeDonnées %}
traitement donnée courante
{% endfor %}
• {% for clé,donnée in ensDeDonnées %}
traitement clé et donnée courantes
{% endfor %}
• {% for donnée in ensDeDonnées if bool_expr
%}
traitement donnée courante
{% endfor %}
• {% for donnée in ensDeDonnées %}
traitement donnée courante
{% else %}
traitement ensDeDonnées vide
{% endfor %} 37
38. Moteur de template Twig
exemple sur les structures de contrôle
1) Ajoutez à FirstController
38
2) Dans templates/first/, éditez notes.html.twig
Requêtez le chemin « /notes »
39. Moteur de template Twig
inclusion d’un template
• Syntaxe d’inclusion d’un template dans un autre
{{ include("chemin/vers/template/à/inclure" }}
• Le template inclus a accès à toute variable du template
enveloppant.
39
40. Moteur de template Twig
héritage d’un template
• Template de base
contient les éléments communs de l’interface
définit des « blocks » à remplir ou à compléter par des
templates enfants
{% block nomDuBlock %} … {% endblock %}
Les « blocks » peuvent être imbriqués
• Template enfant
doit d’abord étendre le template de base
{% extends 'chemin/vers/template/de/base' %}
redéfinit tout « block » qu’il souhaite remplir en
oécrasant son contenu de base
o rajoutant du contenu avec {{ parent() }}
conserve le contenu de base de tout « block » non redéfini
40
41. Moteur de template Twig
exemple template parent
Éditez templates/layout.html.twig
41
42. Moteur de template Twig
exemple template enfant
Éditez templates/first/notes.html.twig
42
Requêtez le chemin « /notes »
43. BDD
sommaire
1) Présentation et installation de Doctrine
2) Configurer et créer la base de données
3) Générer une entité
4) Créer la table correspondant à une entité avec les migrations
5) Modifier une entité
6) Persister un nouvel objet
7) Récupérer des objets
8) Modifier un objet
9) Supprimer un objet
43
44. BDD
présentation et installation
• Doctrine = ORM (Object-Relation Mapper) permettant de
faciliter la communication avec une base de données
• Entité = classe qui fait correspondre un objet PHP à une table
• Objet de l’entité enregistrement de la table
• Commande d’installation de Doctrine
composer require symfony/orm-pack
44
Table
apprenants
id prenom age
1 Ali 23
Classe
Apprenant
id
prenom
age
Objet
Apprenant
id : 1
prenom : Ali
age : 23
O
R
M
45. BDD
configurer et créer la base de données
• Configurer la bdd
Dans la variable d'environnement DATABASE_URL du fichier
.env :
DATABASE_URL="mysql://db_user:db_password@127.0.
0.1:3306/db_name?serverVersion=5.7"
Exemple
DATABASE_URL="mysql://root:@127.0.0.1:3306/symfony
-classroom"
• Créer la bdd avec la commande (le serveur de bdd doit être actif)
php bin/console doctrine:database:create
46. BDD
générer une entité
• Générer une entité
Commande : php bin/console make:entity
script interactif qui demande le nom de l’entité ainsi que les
caractéristiques de chacun de ses attributs (id, clé primaire et
auto-incrémenté, est créé automatiquement)
Résultat
oClasse :
src/Entity/Nom_entité.php
o Repository :
src/Repository/Nom_entitéRepository.php
où les requêtes principales seront codées.
• Exemple
Créer l’entité Apprenant avec les attributs prenom et age.
L’id, clé primaire et auto-incrémenté, sera créé automatiquement
46
47. BDD
migration
• Une migration permet de créer, de mettre à jour et de suivre
les évolutions d’un schéma de base de données.
• Commande pour créer une migration
php bin/console make:migration
• La migration (au format VersionDateTime.php) sera créée
dans le dossier migrations et contiendra deux méthodes
up() : exécutée lorsque la migration est lancée
down() : exécutée lorsque la migration est annulée
• Commande pour lancer les migrations
php bin/console doctrine:migrations:migrate
• Exemple
1) Créez une migration
2) Lancez les migrations pour que la table apprenants soit
créée 47
48. BDD
persister un nouvel objet
• Dans une action d’un contrôleur
1) Créer un objet de l’entité puis renseigner ses attributs
NB : importer la classe de l’entité
use AppEntityNom_entité
2) Récupérer le service EntityManager
$em = $this->getDoctrine()->getManager();
3) Signaler le souhait de persister l’objet (aucune requête
SQL ne sera exécutée à ce stade)
$em->persist(nomObjet);
4) Demander l’exécution de la requête d’insertion
$em->flush();
• L’objet inséré reçoit un id récupérable par $nomObjet->getId()
• Les transactions expliquent $em->persist() et $em->flush()
48
49. BDD
persister un nouvel objet - exemple
49
Testez avec un client REST
Dans FirstController, ajoutez
use AppEntityApprenant; et l’action suivante :
50. BDD
récupérer des objets
• Dans une action d’un contrôleur
1) récupérer le repository de l'entité
$repo = $this->getDoctrine()->getRepository(NomEntité::class)
2) Récupérer l’entité avec la methode find() du repository
$nomObjet = $repo->find($id);
• Autres méthodes du repository
findOneBy(['nomAttribut1' => Valeur, 'nomAttribut2' => Valeur, …])
trouver un objet à partir d’un ou de +sieurs de ses attributs
findBy(['nomAttribut1' => Valeur], ['nomAttribut2' => Valeur], …)
trouver +sieurs objets à partir d’un ou de +sieurs d’attributs
findAll() trouver tous les objets
50
51. BDD
récupérer un objet - exemple
51
Testez les chemins « apprenants/1 » et « apprenants/0 »
52. BDD
modifier un objet
Dans une action d’un contrôleur
1) Récupérez le service EntityManager
$em = $this->getDoctrine()->getManager();
2) Récupérez l’objet avec la methode find() du repository
$nomObjet = $em->getRepository(NomEntité::class)-
>find($id)
3) Modifier l’objet
4) Invoquez la méthode flush() de l’EntityManager
52
54. BDD
supprimer un objet
Dans une action d’un contrôleur
1) Récupérez le service EntityManager
$em = $this->getDoctrine()->getManager();
2) Récupérez l’objet avec la methode find() du repository
$nomObjet = $em->getRepository(NomEntité::class)->find($id);
3) Invoquez la méthode remove() de l’EntityManager
$em->remove($nomObjet);
4) Invoquez la méthode flush() de l’EntityManager
54
56. Formulaires
présentation et installation
• Formulaire = interface entre l’utilisateur et l’application
• Principal objectif : permettre à un utilisateur d’initialiser ou de
modifier les attributs d'un objet métier (ex : apprenant)
• Commande pour installer les fonctionnalités des formulaires
composer require symfony/form
56
57. Formulaires
construction
Dans une action d’un contrôleur
1) Créer un objet métier
NB : sa classe est à importer
2) Créer un objet formBuilder avec le constructeur
createFormBuilder() recevant en paramètre l’objet métier
3) Ajouter un (ou +sieurs) champ(s) au formulaire à construire
avec la méthode add() du formBuilder. add() reçoit
a) le nom d’un attribut de l’objet métier
ou bien 'save' (bouton de soumission)
b) le nom de la classe du type de cet attribut
NB : la classe est à importer
4) Récupérer le formulaire créé avec getForm() du formBuilder
5) Permettre l’affichage du formulaire dans une vue avec
createView() du formulaire
57
59. Formulaires
affichage
• Afficher le formulaire avec l’une des méthodes
(form en paramètre est une variable transmise par le contrôleur )
1) {{ form(form) }}
2) {{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
• Personnaliser un label
1) {{ form_label(form.NomAttribut, 'Label personnalisé') }}
2) {{ form_widget(form.NomAttribut) }}
pour afficher le champ associé au label
59
61. Formulaires
gestion de la soumission
Dans l’action où a été construite le formulaire, juste après avoir
récupéré l’objet formulaire
1) Récupérer les données soumises et hydrater l’objet métier grâce
à la méthode handleRequest() de l’objet formulaire
2) Vérifier la validité des données soumises avec la méthode
isValid() de l’objet formulaire avant de traiter (sauvegarder en
base de données, intégrer dans une réponse, …) l’objet métier
61
composer create-project symfony/framework-standard-edition nomDuProjet pour la dernière version stable
https://symfony.com/doc/5.2/setup.html
https://getcomposer.org/download/
En cas de Pbl de timezone
php -i | grep php.ini
open etc/
Créer php.ini en dupliquant php.ini.default
date.timezone = « Africa/Dakar »
En cas d’erreur : Cannot redeclare class Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser
Dans Web/app_dev.php, commenter la ligne «$kernel->loadClassCache(); »
Problème 2 : pour charger une vue
unable to find template index.html.twig symfony 3.4
Solution
Dans app/config/config.yml, dans la partie « Framework : » rajouter
templating:
engines: ['twig']
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
{% for user in users if user.active %}
<li>{{ user.username|e }}</li>
{% endfor %}
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )
Ctype : Vérification des types de caractères (alpha, alphanum, ctrl, entier, imprimable, minus, maj, blanc, … )