Zend Framework 2 – 构造函数中的类型提示 – IDE 抱怨类型

Zend Framework 2 – type hinting in constructor – IDE complains about type

在 Zend Framework 2 模块中,我使用闭包作为工厂:

'controllers' => [
    'factories' => [
        'ZendSkeletonModule\Controller\Skeleton' => function(AbstractPluginManager $pm) {
            return new Controller\SkeletonController($pm->getServiceLocator()->get('Doctrine\ORM\EntityManager'));
        },
    ],
],

虽然这没有任何问题,但我的 IDE(PHP Storm)在 $pm->getServiceLocator()->get('Doctrine\ORM\EntityManager') 抱怨并显示以下消息:

Expected \Doctrine\ORM\EntityManagerInterface, got array|object.
Invocation parameter types are not compatible with declared.

那是因为在控制器中,我使用 Doctrine\ORM\EntityManagerInterface 作为类型提示,我明白了。

但是为什么 PHP Storm 会报错,我看不出有什么问题?另外,代码工作正常,所以我有点困惑。我需要在 'help' 和 IDE 中添加某种特殊评论或其他内容吗?

将 EntityManager 分配给带有 PhpStorm 静态分析可以使用的注释的变量。 get 方法本身是不透明的:

use Doctrine\ORM\EntityManager;
// snip
'controllers' => [
    'factories' => [
        'ZendSkeletonModule\Controller\Skeleton' => function(AbstractPluginManager $pm) {
            /** @var EntityManager $entityManager */
            $entityManager = $pm->getServiceLocator()->get(EntityManager::class);
            return new Controller\SkeletonController($entityManager);
        },
    ],
],

一些额外的建议:

  1. 与其使用闭包,不如使用具体工厂 class。这是因为闭包不能被缓存操作码,而且你的配置数组如果包含闭包也不能被缓存。

  2. 一件小事,但假设 PHP 5.5+,请考虑像我在上面的示例中所做的那样使用 \Doctrine\ORM\EntityManager::class,而不是ServiceLocator.