I've recently started using PHPStan (version 0.12.19) on a Symfony 3.4 project but I'm getting an error which seems like it should have been simple to resolve but I'm struggling to figure out.
Currently running at level 7. Here's the error I get when I run:
vendor/bin/phpstan analyse
------ --------------------------------------------------------------------------------------------------------------
Line src/AppBundle/Controller/MapController.php
------ --------------------------------------------------------------------------------------------------------------
94 Parameter #1 $user of static method AppBundle\Entity\MapMarker::createMapMarker() expects
Symfony\Component\Security\Core\User\UserInterface, object given.
This is the important parts of MapController.php:
$user = $this->getUser();
$mapMarker = MapMarker::createMapMarker(
$user,
$latitude,
$longitude
);
The getUser method is the Symfony one so I can't change this part: https://github.com/symfony/symfony/blob/3.4/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php#L444:
/**
* Get a user from the Security Token Storage.
*
* @return UserInterface|object|null
*
* @throws \LogicException If SecurityBundle is not available
*
* @see TokenInterface::getUser()
*
* @final since version 3.4
*/
protected function getUser()
{
if (!$this->container->has('security.token_storage')) {
throw new \LogicException('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle".');
}
if (null === $token = $this->container->get('security.token_storage')->getToken()) {
return null;
}
if (!\is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return null;
}
return $user;
}
And the important parts of MapMarker.php:
/**
* @param UserInterface $user
* @param double $latitude
* @param double $longitude
*/
private function __construct(UserInterface $user, $latitude, $longitude) {
$this->createdBy = $user;
$this->latitude = $latitude;
$this->longitude = $longitude;
}
/**
* @param UserInterface $user
* @param double $latitude
* @param double $longitude
* @return MapMarker
*/
public static function createMapMarker(UserInterface $user, $latitude, $longitude): MapMarker
{
return new self($user, $latitude, $longitude);
}
When I dump out $user instanceof UserInterface
it returns true - so as far as I can tell it IS passing a UserInterface object, not just an "object" as PHPStan is indicating.
And finally, here's my phpstan.neon config file:
parameters:
level: 7
paths:
- src
- tests
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
What am I missing?
I think you at least got whats the proble: The return type of the method getUser
is @return UserInterface|object|null
while createMapMarker
expects an instance of UserInterface
.
Before calling createMapMarker
you should check that the return value of getUser
is actually an instance of UserInterface
and probably a simple /** @var UserInterface $user */
right on top the the $user
variable declaration will fix.