Récupération d'une entité Doctrine avec le bon typage

Publié le 14/05/2022 • Mis à jour le 14/05/2022


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

Dans ce bout de code, nous voyons comment récupérer une entité Doctrine avec le bon typage. On peut utiliser la fonction find(), elle retourne une entité ou null. Mais quid si l'on est sûr que l'entité existe ? Il n'y a pas de fonction native Doctrine pour cela. Elle est bien sûr facile à faire puisqu'on a à tester si la variable retournée est nulle et lever une exception si c'est le cas. En discutant sur le Slack Symfony, certains m'ont signalé utiliser une fonction get() pour cela. Ça semble effectivement approprié, car lorsque l'on "cherche", on est pas sûr du résultat alors qu'il semble logique d'avoir un type de retour particulier sur un "getter". De plus, PHP 8 permet désormais d'utiliser les exceptions dans des expressions, rendant le code plus concis. On évite de forcer le type de la variable avec un docblock pour avoir un code plus lisible.


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

use App\Entity\Article;
use App\Repository\ArticleRepository;

/**
 * J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
 * Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
 * ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Les services sont injectés dans le constructeur du contrôleur principal.
 *
 * @property ArticleRepository $articleRepo
 */
trait Snippet201Trait
{
    public function snippet201(): void
    {
        // No need for a docblock or to test id $snippet is null
        $snippet = $this->articleRepo->find(201) ?? throw new \RuntimeException('Snippet 201 not found!');

        echo get_debug_type($snippet).PHP_EOL;
        echo $snippet->getName().PHP_EOL; // $snippet is correcly consired as an article, so PHPStan is happy

        $snippet = $this->get_(201); // get has the Article type and isn't nullable
        echo $snippet->getName();

        // That's it! 😁
    }

    /**
     * In the Doctrine article repository, the get() function would like this. I
     * can't name the function get() has I am in a controller context and it already
     * exists and allows to retrieve a service.
     */
    public function get_(int $id): Article
    {
        return $this->articleRepo->find($id) ?? throw new \RuntimeException("Snippet $id not found!");
    }
}

 Exécuter le snippet  Plus sur Stackoverflow   Lire la doc  Plus sur le web  Snippet aléatoire