2
votes

How to get User class instead of Userinterface when i do :

$this->security->getUser() (Security is Symfony\Component\Security\Core\Security;)

By Example (and its just an example :), i have this custom function :

public function getUser(User $user){
}

and when i do that :

public function __construct(
        Security $security,
    ) {
        $this->security = $security;
    }

getUser($this->security->getUser());

I have a warning :

getUser expects App\Entity\User, Symfony\Component\Security\Core\User\UserInterface|null given.

2
Doesn't your user implement UserInterface? - Nico Haase
Yes it is : class User implements UserInterface - Marcel Patulacci
Where do you get this warning? Is this from a static analysis tool like psalm or phpstan? - dbrumann
Yep, phpstan (and phpstorm too) - Marcel Patulacci
If it's what your editor is telling you, and not what Symfony debugger is telling you, then ignore it. PhpStorm can't resolve it right. - Preciel

2 Answers

3
votes

When a code analysis tool like phpstan or psalm warns you about a type mismatch there are multiple ways to deal with it.

Most likely you want to change your method signature and then handle the cases, the message complains about, e.g. like this:

public function getUser(UserInterface $user = null)
{
    if (null === $user || ! $user instanceof User) {
        // do something about the wrong types, that you might get from getSecurity()->getUser(), e.g. return or throw an exception
        throw Exception(sprintf('Expected App\\Entity\\User, got %s', $user === null ? 'null' : get_class($user)));
    }

    ... your logic
}

Now your method accepts both the interface and null that might get in there. You could also do the error handling before calling your getUser method and leave it as is, so instead of just getUser($this->security->getUser());:

$temporaryUser = $this->security->getUser();

if (!$temporaryUser instanceof User) {
    throw Exception(sprintf('Expected App\\Entity\\User, got %s', $user === null ? 'null' : get_class($user))); 
}

getUser($temporaryUser);

If you are sure that the code will not run into problems, you can also ignore certain error messages by creating a phpstan.neon in your project root. See: https://github.com/phpstan/phpstan#ignore-error-messages-with-regular-expressions

-1
votes

If $this->security->getUser() calls Symfony's core security class to return a user, it will always return an object that implements UserInterface - that's what the return type of that class defines (either implicitly through a proper return type, or through PHPDoc). This can not be altered by your own application.

To overcome your problem, you own method getUser should use this interface as the parameter type to it's argument. In that method, you can check for a more specific class (like: if($argument instanceof User)), but not in the method's function signature.