更正 PHPStan 在 Symfony 项目的 UserInterface 上抛出的类型提示错误
Correct type hint error thrown by PHPStan on UserInterface in Symfony project
我最近开始在 Symfony 3.4 项目上使用 PHPStan(版本 0.12.19),但出现错误这似乎应该很容易解决,但我正在努力弄清楚。
目前 运行 处于 7 级。这是我在 运行 时遇到的错误:
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.
这是MapController.php的重要部分:
$user = $this->getUser();
$mapMarker = MapMarker::createMapMarker(
$user,
$latitude,
$longitude
);
getUser 方法是 Symfony 方法,所以我无法更改这部分: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;
}
以及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);
}
当我转储 $user instanceof UserInterface
时,它 returns 是真的 - 据我所知,它正在传递一个 UserInterface 对象,而不仅仅是 PHPStan 所指示的 "object"。
最后,这是我的 phpstan.neon 配置文件:
parameters:
level: 7
paths:
- src
- tests
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
我错过了什么?
我想你至少明白了问题所在:方法 getUser
的 return 类型是 @return UserInterface|object|null
而 createMapMarker
需要 [=13= 的实例].
在调用 createMapMarker
之前,您应该检查 getUser
的 return 值是否实际上是 UserInterface
的一个实例,并且可能是一个简单的 /** @var UserInterface $user */
上面 $user
变量声明将修复。
我最近开始在 Symfony 3.4 项目上使用 PHPStan(版本 0.12.19),但出现错误这似乎应该很容易解决,但我正在努力弄清楚。
目前 运行 处于 7 级。这是我在 运行 时遇到的错误:
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.
这是MapController.php的重要部分:
$user = $this->getUser();
$mapMarker = MapMarker::createMapMarker(
$user,
$latitude,
$longitude
);
getUser 方法是 Symfony 方法,所以我无法更改这部分: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;
}
以及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);
}
当我转储 $user instanceof UserInterface
时,它 returns 是真的 - 据我所知,它正在传递一个 UserInterface 对象,而不仅仅是 PHPStan 所指示的 "object"。
最后,这是我的 phpstan.neon 配置文件:
parameters:
level: 7
paths:
- src
- tests
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
我错过了什么?
我想你至少明白了问题所在:方法 getUser
的 return 类型是 @return UserInterface|object|null
而 createMapMarker
需要 [=13= 的实例].
在调用 createMapMarker
之前,您应该检查 getUser
的 return 值是否实际上是 UserInterface
的一个实例,并且可能是一个简单的 /** @var UserInterface $user */
上面 $user
变量声明将修复。