Getting a Doctrine entity with the correct type hint

Published on 2022-05-14 • Modified on 2022-05-14

This snippet shows how to fetch a Doctrine entity from a repository with the correct type hint. We can use the find() function to retrieve a given entity. It returns an entity or null. But what if we are sure the entity exists? There is no native Doctrine function for that. It's, of course, relatively easy to create as we have to test if the object is null and throw an exception in this case. When talking on the Symfony slack, some pointed out that they used a get() function for this purpose. It's seems appropriate, as when "finding", we are unsure of the result, but it's seems logical to have a correct typehint for a "getter". Moreover, PHP 8 allows exceptions to be used as expression, making the code more concise! It avoids forcing the variable type with a docblock or test if it is null. It also makes the code more readable and straightforward.


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

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

/**
 * I am using a PHP trait to isolate each snippet in a file.
 * This code should be called from a Symfony controller extending AbstractController (as of Symfony 4.2)
 * or Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Services are injected in the main controller constructor.
 *
 * @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!");
    }
}

 Run this snippet  More on Stackoverflow   Read the doc  More on the web  Random snippet