PRÉSENTATION DU COURS

Les services dans symfony

Les fondamentaux pour utiliser les services dans Symfony

Les service, élement fondamental de Symfony

En réalité Symfony n'est rien d'autre qu'une collectio d'objet ultra spécialisés qui marchent ensemble !

Par exemple, le routeur est un objet qui matche sur des routes et génère des urls, twig un objet qui s'occupe de créer et afficher les templates, le logger qui permet d'enregistrer des messages du système dans un fichier (dans notre cas var/log/dev.log car nous sommes en dev, mais pour de la prod ce sera var/log/prod.log).

Symfony utilise d'ailleurs déjà ce système de logging pour enregistrer les erreurs ou autre information du système.

De manière plus générale, pensez Symfony comme un emsemble d'objet, car tout et absolument est un objet ultra spécialisé dans Symfony.

Ces objets ont d'ailleurs des noms: Les services

Que sont les services

Comme dit précédement les services sont des objets ultra spécialisés, cela veut dire qu'il va exécuter des tâche dans un contexte bien précis, par exemple pour les trois exemples suivantes, nous allons utiliser trois services différent car ils ont un contexte très différent.

  • Générer une url
  • Envoyer un email
  • Sauvegarder en base de données

On pourrait bien sûr faire un service avec toutes ces fonctionnalités, mais bonne chance pour le maintenir quand votre fichier fera 10 000 lignes, Aha! (Après tout si vous aimez vous faire du mal, ça ne regarde que vous 😏)

Symfony rassemble un grand nombre de services, et il serait plus judiceux de les voir comme des outils que vous pouvez utiliser.

Un peu à la manière d'un menuisier, d'un garagiste ou de Roger qui collectionne les outils dans son garage, vous allez avoir une caisse à outil de plusieurs milliers de services, pratique non ? Donc n'hésitez pas à voir si Symfony ne dispose pas d'une fonctionnalité pouvant vous aider avant de commencer à coder !

À partir de maintenant, le cours sera surtout sur où trouver les services et comment s'en servir.

Plus vous maitrisez d'outil, plus vous allez être efficace et augmenter la qualité de vos projets Symfony !

Exemple avec le service de logging

Pour voir un peu à quoi ressemble de système de logging, allez voir dans le fichier var/log/dev.log, pour voir un petit peu les logs générés par notre projet Symfony.

⚠ Le fichier est organisé de la manière suivante : Chaque nouveau message de logging est en bas du fichier, donc le message le plus vieux sera en haut et le plus récent en bas du fichier

Si vous avez un Mac, Linux, ou que vous utilisez git bash pour pouvez utiliser la commande tail pour voir la fin du fichier. (Je vous laisse vous renseigner sur son utilisation)

Ok très bien, ça me fait une belle jambe de savoir ça, mais à quoi ça me sert ?

Très bonne question Svetlana, quelque peu aggressive, mais très bonne question.

Comme je vous l'ai dit tout à l'heure, à peu près tout est un service dans Symfony, les services ne sont pas limité qu'à Symfony en interne, vous pouvez très bien les utiliser vous aussi !

Nous allons donc voir comment ajouter nos propres messages dans le fichier de log via le service de logging !

Injecter un service dans notre controller

Dans les versions précédentes de Symfony, c'était différent, mais dans cette nouvelle version, les choses ont été simplifiées pour encore plus facilement utiliser les services.

Ça se passe dans votre controller, si vous souhaitez ajouter un service il va falloir l'ajouter en argument à la méthode du controller dans laquelle vous voulez l'utiliser.

Petite chose spéciale, vous allez devoir lui donner un type spécial pour dire à Symfony que vous voulez le service logger, Symfony ne lit pas encore dans vos esprit malheureusement ! Voilà le type en question : LoggerInterface.

Vous pouvez ensuite lui donner n'importe quel nom, selon ce qui vous semble judicieux. (Attention, je juge votre santé mentale au nom de vos variable, vous êtes prévenus).

Et maintenant un petit exemple dans le code :

<?php

namespace App\Controller; 

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Psr\Log\LoggerInterface; // Important de récupérer la classe pour l'utiliser dans nos fichiers

class ExempleController extends AbstractController
{
    /**
    * @Route("/", name="homepage") // ajout d'une propriété name
    **/
    public function index(LoggerInterface $logger) {
        return $this->render('index.html.twig', [
            'title' => 'hello world'
        ]);
    }

    // Il y a le reste, mais la flemme de tout écrire
}

Donc maintenant dans ma méthode index, j'ai accès à mon logger !

! Pour les chanceux sur phpstorm, tapez simplement le début du type, phpstorm vous autocomplétera et ajoutera le use en fonction de votre choix, pratique !

On va désormais utiliser une méthode du logger appelée info et prenant une chaine de caractère.

! Il y a bien sur des configuration spéciales que vous pouvez utiliser pour le logger, vous pouvez les voir sur ce lien

OK, maintenant place au code :

<?php

namespace App\Controller; 

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Psr\Log\LoggerInterface; // Important de récupérer la classe pour l'utiliser dans nos fichiers

class ExempleController extends AbstractController
{
    /**
    * @Route("/", name="homepage") // ajout d'une propriété name
    **/
    public function index(LoggerInterface $logger) {
        $logger->info('Webédiable');
        return $this->render('index.html.twig', [
            'title' => 'hello world'
        ]);
    }

    // Il y a le reste, mais la flemme de tout écrire
}

Lancez votre homepage, allez voir la fin de votre fichier, et normalement, vous devez avoir votre petit message à la fin du fichier, un peu de cette manière la :

résultat du logging webédiable

Vous allez désormais pouvoir logger comme un fou vos projet pour savoir ce qu'il se passe, génial !

En réalité, les logs sont très important, notament en cas d'erreur ou chose bizzare dans votre système ce seront eux qui vous aiderons à trouver les erreurs. Donc n'hésitez pas à logger assez, mais pas trop quand même.

C'est comme le sel dans vos pâtes, trop c'est inmangeable, pas du tout c'est fâde, et juste un peu c'est satisfaisant.

Mais comment ça marche ça ?

Comme dit précédement symfony ce sert du type pour détecter ce que nous avons besoin, et lui faire passer LoggerInterface signale que nous avons besoin d'un logger dans cette variable.

C'est ce que l'on appelle de l'auto-wiring ! Servez vous en pour impressionnez vos amis non technique.

! La chose intéressante, c'est que l'ordre importe peu tant que vos arguments sont typés. Si vou n'aimez pas vos collègues, vous pouvez très bien mélanger les arguments des route et vos services pour faire reigner la colère, crises cardiaques et autres avcs dans votre entreprise !

! Les éléments non typés sont considéré comme des arguments du routeur (les choses comme {name} dans les routes), et seront remplis par les arguements passés dans l'url

Petite choses sympa avec ces interface pour récupérer des services, c'est qu'il existe une commande Symfony pour afficher tous les types que vous pouvez utiliser dans vos controllers :

php bin/console debug:autowiring

Et là BOOM, c'est comme au supermarché, vous avez juste à choisir ce dont vous avez besoin 😎👍

! Dès que vous installez un nouveau package, vous allez avoir de nouveaux type de disponibles, n'hésitez pas à aller voir lorsque vous installez des pacjages !

Utiliser twig en service

Comme nous l'avons dit précédement dans Symfony tout est un service, donc twig est lui même un service !

Jusqu'à présent nous utilisions $this->render dans nos controller, qui est plutôt pratique, en réalité, ce n'est rien d'autre qu'un shortcut pour accéder au service de twig.

Imaginons un instant que ce shortcut n'existe pas, nous allons donc devoir utiliser le service twig.

Si vous refaites un coup de php bin/console debug:autowiring, vous devirez pouvoir voir Environnement qui apparatient à twig, et c'est le type que nous allons utiliser pour récupérer twig.

<?php

namespace App\Controller; 

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Psr\Log\LoggerInterface; 
use Twig\Environment; // Ne pas oublier le use

class ExempleController extends AbstractController
{
    /**
    * @Route("/", name="homepage") // ajout d'une propriété name
    **/
    public function index(LoggerInterface $logger, Environment $twigEnvironment) {
        $logger->info('Webédiable');
        $html = $twigEnvironment->render('index.html.twig', [
            'title' => 'hello world'
        ]);

        return new Response($html);
    }

    // Il y a le reste, mais la flemme de tout écrire
}

Hop ça marche comme avant !

Comme vous avez pu le voir, nous sommes désormais obligé de récupérer le html et ensuite de le convertir en réponse. Ce n'est pas quelque chose que je conseille, $this->render reste plus simple, en s'occupant de récupérer le service et de le transformer en Response pour vous.

Le point ici est surtout de montrer que tout peut être fait avec des services, une fois que vous les maitrisez, vous pouvez faire n'importe quoi depuis n'importe où, ce qui est très pratique !

Retransformez votre code pour utiliser $this->render ou laissez le comme cela si vous le souhaitez.

Conclusion

Vous savez désormais comment utiliser des services, où les trouver et comment les intégrer à votre code.

Si vous avez tout compris et résussis jusqu'à présent, c'est très bon signe car vous avez vu l'essentiel de symfony.

Désormais le cours va se pencher plus précisément sur des services précis, qui sont la base de Symfony !

Envie de discuter du contenu ?

logo twitter @GarnierKristen