0

I'm implementing PHPStan into my application and also testing Psalm for automatic fixes, however I'm unable to make them read entity class strings (with colon) fe:

$repository = $this->em->getRepository('MyApp:EntityClass');

turns into Psalm error:

ERROR: UndefinedClass - src/Controller/MyController.php:229:48 - Class, interface or enum named MyApp:EntityClass does not exist (see https://psalm.dev/019)

and in PHP Stan

  Line   src/Controller/MyController.php                                                                                                               
 ------ --------------------------------------------------------------------------------------------------------------------------------------------------- 
  229    Parameter #1 $className of method Doctrine\ORM\EntityManagerInterface::getRepository() expects class-string<MyApp:EntityClass>, string given.  
 ------ --------------------------------------------------------------------------------------------------------------------------------------------------- 

Easiest way to fix this is to use \EntityClass::class instead of a string 'MyApp:EntityClass' however I would like to avoid that. Probable I need to use some annotation to make both tools interprete string correctly, but I have problems figuring out which one. It would also be nice to have it avaialble globaly via entire app, and don't use annotation each time I call a class via string. Currently I've just added this error to ignored ones but would like to know how to fix that.

2
  • Did you try the PHPStan extension for Doctrine? The link is this: github.com/phpstan/phpstan-doctrine However, using \EntityClass::class is the best option. Commented Aug 4, 2022 at 12:40
  • "Easiest way to fix this is to use \EntityClass::class instead of a string 'MyApp:EntityClass' however I would like to avoid that." why you want to avoid that? it's not the recommended way IIRC Commented Aug 11, 2022 at 18:56

1 Answer 1

0

Easiest way to fix this is to use \EntityClass::class instead of a string 'MyApp:EntityClass' however I would like to avoid that.

You already wrote the recommended answer. Using shortname alias is deprecated since doctrine/orm v2.10. It'll probably be removed in v3.0. You should consider upgrading.

That said, this is the only sustainable solution.

$repository = $this->em->getRepository(EntityClass::class);

Install phpstan/phpstan-doctrine

Using phpstan without phpstan-doctrine is not recommended (while interpreting types of a doctrine entity). Install the phpstan extension phpstan/phpstan-doctrine and configure it. It interpretes types of QueryBuilder and Repository inside your project; like EntityManager::getReposiotry(EntityClass::class):

composer require --dev phpstan/phpstan-doctrine
# phpstan.neon
parameters:
    doctrine:
        objectManagerLoader: tests/object-manager.php

Optional: automatic refactoring

That said, you really should update your code base. To ease that process, you could use rector using the EntityAliasToClassConstantReferenceRector. Correctly configured, you're done in seconds.

composer require --dev rector/rector
// rector.php

<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Doctrine\Rector\MethodCall\EntityAliasToClassConstantReferenceRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig->phpstanConfig(__DIR__.'/phpstan.neon');

    $rectorConfig->ruleWithConfiguration(EntityAliasToClassConstantReferenceRector::class, [
        EntityAliasToClassConstantReferenceRector::ALIASES_TO_NAMESPACES => [
            'MyApp' => 'App\Entity',
        ]
    ]);
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.