Programmation PHP/Symfony

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche


Présentation[modifier | modifier le wikicode]

Symfony2.svg

Symfony (parfois abrégé SF) est un cadriciel MVC libre écrit en PHP (> 5). En tant que framework, il facilite et accélère le développement de sites et d'applications Internet et Intranet.

Fonctionnalités[modifier | modifier le wikicode]

Symfony propose entre autres :

  • Une séparation du code en trois couches, selon le modèle MVC, pour une plus grande maintenabilité et évolutivité.
  • Un templating simple, basé sur PHP et des jeux de "helpers", ou fonctions additionnelles pour les gabarits... Comme alternative au PHP, on peut aussi utiliser le moteur de templates Twig dont la syntaxe est plus simples.
  • Des performances optimisées et un système de cache pour garantir des temps de réponse optimums.
  • Le support de l'Ajax.
  • Une gestion des URL parlantes (liens permanents), qui permet de formater l'URL d'une page indépendamment de sa position dans l'arborescence fonctionnelle.
  • Un système de configuration en cascade qui utilise de façon extensive le langage YAML.
  • Un générateur de back-office et un "démarreur de module" (scaffolding).
  • Un support de l'I18N - Symfony est nativement multi-langue.
  • Une couche de mapping objet-relationnel (ORM) et une couche d'abstraction de données (cf. Doctrine et son langage DQL[1]).
  • Une architecture extensible, permettant la création et l'utilisation de plugins.
  • Assetic : gestionnaire de fichiers .css et .js.
  • Swift Mailer : messagerie électronique.

Critique[modifier | modifier le wikicode]

Il peut être redondant de mettre à jour des fichiers .yml pour déclarer les services, en plus de leurs classes .php (qui peuvent se contredire) à chaque changement de structure. C'est pourquoi depuis Symfony 4, l'autowiring est activé par défaut. Toutefois il ne fonctionne pas avec les classes ayant autre chose que des services dans leurs constructeurs[2].

La présente page se veut une prise en main la plus rapide possible du framework qui peut paraitre peu intuitif au début.

Créer un projet[modifier | modifier le wikicode]

Page d'accueil par défaut.

Symfony 4[modifier | modifier le wikicode]

Avec Composer :

Arborescence des composants[modifier | modifier le wikicode]

  • bin : binaires.
  • config : fichiers .yml de paramétrage global. Les contenus des fichiers suffixés "-dev.yml" ou "-prod.yml" surchargent ceux des non suffixés selon le contexte. Ce qui permet par exemple d'utiliser des mots de passe différents en local et en production.
  • public (anciennement "web") : site accessible en HTTP. Il contient les "assets" : les fichiers CSS et JavaScript.
  • src : code source du projet.
  • templates (ex : Twig).
  • tests.
  • var : logs.
  • vendor : bibliothèques des dépendances ("bundles" téléchargés[3]).

Symfony 3[modifier | modifier le wikicode]

Arborescence des composants[modifier | modifier le wikicode]

  • Projet : arborescence incluant le framework et le code source de sa propre application.
    • app : applications.
      • config : fichiers .yml de paramétrage global. Les contenus des fichiers suffixés "-dev.yml" ou "-prod.yml" surchargent ceux des non suffixés selon le contexte. Ce qui permet par exemple d'utiliser des mots de passe différents en local et en production.
      • Resources\views : templates .twig.
    • bin : binaires.
    • src : code source ("bundles" de l'utilisateur).
    • vendor : bibliothèques des dépendances ("bundles" téléchargés).
    • web : site accessible en HTTP. Il contient les "assets" : les fichiers CSS et JavaScript.

Pour créer un projet, il existe plusieurs techniques au choix :

Composer.phar[modifier | modifier le wikicode]

Avec Composer : php composer.phar create-project symfony/framework-standard-edition MonProjet1.

Symfony.phar[modifier | modifier le wikicode]

Créer l'installeur par ces commandes ou bien en téléchargeant le fichier à l'adresse qui y figure :

GitHub[modifier | modifier le wikicode]

Avec GitHub : https://github.com/symfony/symfony.


Lancer le projet[modifier | modifier le wikicode]

Mode dev : le serveur Web intégré[modifier | modifier le wikicode]

Une fois le nouveau projet créé, il suffit de suivre les consignes affichées dans la console :

   5.15 MB/5.15 MB ============================================================  100%

Preparing project...

OK  Symfony 3.1.4 was successfully installed. Now you can:

   * Change your current directory to C:\Program Files (x86)\EasyPHP\eds-www\MonProject1

   * Configure your application in app/config/parameters.yml file.

   * Run your application:
       1. Execute the php bin/console server:run command.
       2. Browse to the http://localhost:8000 URL.

L'URL permet d'accéder à toutes les pages du site grâce au serveur Web intégré à Symfony, tant que la console shell est active.

Sous Windows, pour lancer le projet rapidement et facilement, on peut créer un fichier MonProjet1.cmd :

cd "C:\Program Files (x86)\EasyPHP\eds-www\MonProject1"
start http://localhost:8000/
php bin\console server:run
pause

La page de bienvenue doit s'ouvrir ensuite dans le navigateur Web par défaut.

Pour rendre le site web accessible à d'autres machines, le lancer avec son IP, par exemple :

php bin/console server:start 192.168.1.8:80

Cela nécessite d'arrêter le serveur Web qui prenait le port 80.

Mode prod[modifier | modifier le wikicode]

Pour que le site soit accessible en production, il faut qu'il tourne sur un serveur Web installé sur le système d'exploitation.

Par exemple avec Apache, il faut ajouter un vhost et un nom de domaine dédiés au site Symfony[4][5]. Pour le test, le domaine peut juste figurer dans /etc/hosts.

Attention !
link={{{link}}}

Le nom de domaine du site doit absolument rediriger vers le dossier /public. En effet, si on cherche à utiliser le site Symfony dans le sous-répertoire "public" d'un autre site, la page d'accueil s'affichera mais le routing ne fonctionnera pas.

Les différences avec l'environnement de dev se configurent ensuite dans config/packages. On constate pas exemple l'absence du web_profiler par défaut en prod.

Configurer le projet[modifier | modifier le wikicode]

La liste des commandes disponibles en console est visible avec :

php bin\console
Attention !
link={{{link}}}

Dans Symfony 2 c'était php app\console.

Parmi les principales commandes, on trouve :

  • php bin/console generate:bundle
  • php bin/console cache:clear
  • php bin/console debug:router
  • php bin/console doctrine:migrations:generate; chown 1001:1001 -R app/DoctrineMigrations

Par ailleurs, les fichiers .yml de configuration globale sont dans app\config\. Par exemple le mot de passe et l'adresse de la base de données sont modifiables en éditant parameters.yml.

Contrôleur[modifier | modifier le wikicode]

Les contrôleurs Symfony sont les classes qui définissent les opérations à réaliser quand on visite les pages du sites[6]. Par convention, leurs noms se terminent par Controller, les noms de leurs méthodes se terminent par "Action", et les URL qui provoquent leurs exécutions sont définies dans leurs annotations. L'exemple suivant affiche un texte quand on visite l'adresse "/" ou "/helloWorld" :

class HelloWorldController extends AbstractController
{
    /**
     * @Route("/", name="helloWorld")
     * @Route("/helloWorld")
     *
     * @return Response
     */
    public function indexAction(Request $request)
    {
        return new Response('Hello World!');
    }
}

Ces méthodes peuvent déboucher sur plusieurs actions :

  • Response() : affiche un texte, et facultativement un code HTTP en deuxième paramètre (ex : erreur 404).
  • JsonResponse() : affiche du JSON.
  • $this->render() : affiche une page à partir d'un template, par exemple HTML ou Twig.
  • $this->redirect('mon_url') : redirige à une autre adresse.
  • $this->redirectToRoute('nom_de_la_route'); : redirige vers une route du site par son nom.


Les contrôleurs étendent la classe abstraite Symfony\Bundle\FrameworkBundle\Controller\AbstractController. Cela leur permet entre autres, de récupérer les services et paramètres ainsi :

dump($this->get('session'));
dump($this->getParameter('kernel.root_dir'));

Les paramètres sont ceux des fichiers .yml du dossier "config", mais plusieurs autres paramètres sont fournis par Symfony :

  • kernel.root_dir : chemin du site dans le système de fichier.
  • kernel.debug : renvoie vrai si le site est en préprod et faux en prod.

Routing[modifier | modifier le wikicode]

Par exemple pour créer une nouvelle page sur l'URL :

http://localhost:8000/test

Installer le routage :

composer require sensio/framework-extra-bundle
composer require symfony/routing

Par défaut, la page renvoie l'exception No route found for "GET /test". Pour la créer, il faut d'abord générer un fichier contrôleur (rôle MVC), qui fera le lien entre les URL, les données (modèle) et les pages (vue).

Les URL définies dans l"annotation "@Route" d'une méthode exécuteront cette dernière :

<?php
namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;

class TestController extends Controller
{
    /**
     * @Route("/test", name="test")
     */
    public function HelloWorldAction($numero = 0)
    {
        return new Response('Hello World!');
    }
}
?>


Pour créer des alias, c'est-à-dire plusieurs autres URL pointant vers la page ci-dessus, on peut l'ajouter dans les annotations des contrôleurs, ou bien dans app\config\routing.yml :

test:
    path:      /test/{numero}
    defaults:  { _controller: AppBundle:Test:HelloWorld }

A présent http://localhost:8000/test/1 ou http://localhost:8000/test/2 affichent "Hello World!".

Attention !
link={{{link}}}

Une fois routing.yml sauvegardé, l'URL fournie en annotation (/test) ne fonctionne plus.

Vue[modifier | modifier le wikicode]

Pour commencer à créer des pages plus complexes, il suffit de remplacer :

 return new Response('Hello World!');

par une vue Twig :

 return $this->render('helloWorld.html.twig');

Pour installer les bibliothèques JavaScript qui agiront sur ces pages, se positionner dans /public. Exemple :

cd public/
sudo apt-get install npm
npm install --save jquery
npm install --save bootstrap

Ensuite il suffit de les appeler dans /templates/helloWorld.html.twig pour pouvoir les utiliser :

<link rel="stylesheet" href="{{ asset('node_modules/bootstrap/dist/css/bootstrap.min.css') }}">

<script type="text/javascript" src="{{ asset('node_modules/jquery/dist/jquery.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('node_modules/bootstrap/dist/js/bootstrap.min.js') }}"></script>

Modèle[modifier | modifier le wikicode]

Le principe des services Symfony est d'éviter d'instancier la plupart des classes avec des "new" dispersés dans le code, pour les déclarer une seule fois, grâce au container. Ils sont alors instanciés uniquement s'ils sont utilisés (ex : sur la page web courante), grâce au lazy loading du container[7].

Cette déclaration peut se faire en PHP, en YAML ou en XML. On baptise alors le service (il peut y en avoir plusieurs par classe), et on appelle ses arguments par leur nom de service. Exemple :

services:
    app.my_namespace.my_service:
        class: App\myNamespace\myServiceClass
        arguments:
            - '%parameter%'
            - '@app.my_namespace.my_other_service'

Depuis SF2.8, l'autowiring peut être définit à "true" pour injecter automatiquement les arguments connus (ex : une autre classe appelée par son espace de nom), donc sans déclaration manuelle[8].

Les contrôleurs ne sont pas des services mais peuvent les appeler avec la méthode :

$this->get('app.my_namespace.my_service')

Pour déterminer si un service existe depuis un contrôleur :

$this->getContainer->hasDefinition('app.my_namespace.my_service')

Pas de require_once()[modifier | modifier le wikicode]

Les classes natives de PHP doivent être introduites par leur namespace ou bien par l'espace de nom global. Ex :

use DateTime;
echo new DateTime();

ou

echo new \DateTime();


Paramètres[modifier | modifier le wikicode]

Chaque service peut être déclaré avec des paramètres suivants :

Paramètres YAML
Nom Rôle
arguments Définit les arguments du constructeur de la classe, services ou variables.
calls Lance une méthode de la classe, généralement un setter.
alias Crée un autre nom pour un service, qui peut alors être modifié par d'autres paramètres de déclaration (ex : créer une version publique d'un service privé).
parent Nom de la superclasse.
abstract Booléen indiquant si la méthode est abstraite.
public Booléen indiquant une portée publique du service.
shared Booléen indiquant un singleton.

Les tags[modifier | modifier le wikicode]

Quand on doit injecter un nombre indéterminé de services dans un autre, il est possible de le définir avec chacun des services à injecter, en y ajoutant un tag avec le nom du service qui peut les appeler. Ce tag doit néanmoins être défini dans un CompilerPass[9].

Références[modifier | modifier le wikicode]

Voir aussi[modifier | modifier le wikicode]