如何让我的PHP IDE了解依赖注入容器?

时间:2011-06-18 11:42:19

标签: php ide dependency-injection phpstorm

当前情况:我通过使用依赖注入解决了项目中的依赖项。我想通过使用依赖注入容器(DIC)来简化对依赖项和延迟加载类的管理,从而采取下一个逻辑步骤。

我查看了BucketPimplesfServiceContainer,进行了一些测试,非常感谢DIC的工作方式。因为它的简单性和原始力量,我可能会选择Pimple。如果我没有这个问题:

由于DIC提供的抽象,我正在使用的IDE(PHPStorm)不再理解我的代码中发生了什么。它不明白$ container ['mailer']或$ sc->邮件程序正在持有一个类对象。我也试过Netbeans IDE:同样的问题。

这对我来说真的是一个问题因为我的IDE变得无用了。在处理类时,我不想在没有代码提示,自动完成和重构工具的情况下编程。而且我不希望我的IDE在验证代码时发现各种误报。

所以我的问题是:有没有人处理过这个问题并找到了解决方案?

6 个答案:

答案 0 :(得分:56)

您可以定义“手动”变量的类:

/** @var YourClassType $mailer */
$mailer = $container['mailer'];

在PhpStorm(以及standards)中,使用两个星号并在变量名称前写入数据类型。

您可以编写没有变量名称的数据类型(但不包括没有数据类型的名称)。

答案 1 :(得分:43)

虽然您每次访问时都可以告诉IDE您从容器中取出的对象的类型,但最好这样做一次。以下两个解决方案都涉及对容器进行子类化。我刚开始使用Pimple,建议不要这样做。

对于使用通过->访问或通过magic __get方法公开的实例成员的容器,您可以告诉IDE他们持有什么类型。这很好,因为它在代码运行时不涉及任何额外的解析 - 只有IDE会受到它的困扰。

/**
 * My container. It contains things. Duh.
 *
 * @property MyService $service
 * @property MyDao $dao
 */
class MyContainer extends Container { }

对于Pimple和其他充当数组的容器,您可以为您需要的顶级对象创建访问器函数。虽然这意味着在创建容器时需要进行更多解析,但应该只进行一次并保存在APC中。我非常喜欢一种方法而不是数组访问,因为它将易于忘记的数组键放在一个自动完成的方法中。

class MyContainer extends Pimple
{
    /**
     * @return MyService
     */
    public function getMyService() {
        return $this['service'];
    }
}

顺便说一句,对于NetBeans中带有@var的类型提示内联变量,您需要将/*一个星号一起使用。这是一个文档块注释,不适用于/**//。此外,名称出现在类型之前。

public function foo() {
    /* @var $service MyService */
    $service = $container['service'];
    ...
}

答案 2 :(得分:13)

由于IDE没有执行代码,因此他们不知道并需要一些帮助。我知道这适用于Eclipse和其他IDE:提示变量的类型。

Netbeans / Phpstorm / PDT / ZendStudio示例

/* @var $mailer MailerInterface */
$mailer = $sc->mailer

代码完成在$mailer上再次开始工作。

对于PDT来说,重要的是:

  1. 评论仅从一个*开始。
  2. 首先是变量名,而不是提示。
  3. 备选评论变体

    由于需要进行大量讨论,因此IDE之间可能会有所不同。但是,大多数IDE以上述方式支持内联代码变量的变量提示。因此,根据IDE,这可能会有不同的写法,但类似,就像这里有两个星号:

    /** @var $mailer MailerInterface */
    

    PHPDoc兼容性

    如果您模仿内联代码的类var doc-comment,PHPDoc解析器可能会出现问题:

    /** @var MailerInterface $mailer  */
    

    该文档通常用于类变量(@var - Document the data type of a class variable)。然后,PHPDoc在评论之后缺少类变量的定义,这会导致QA负担。

    然而,当用PHPDoc clas-variable样式编写时,一些IDE将为简单变量提供代码完整性。我不知道这对于当前类的代码整合是否有副作用,然后可能会引入一个实际上不存在的新成员。

答案 3 :(得分:7)

对于那些从谷歌来到这里的人。

PHPStorm实际上提供了一种解决此类问题的方法,而不是一遍又一遍地编写PHPDocs - 以described here方式创建和设置.phpstorm.meta.php文件,可以顺利地完成自动完成和类型检查。

答案 4 :(得分:1)

我知道问题只是关于DIC,但有一个Silex Pimple Dumper服务提供程序将容器转储到json文件。同一位作者写了一个plugin for PHPStorm,它可以读取该文件并使用服务名称及其类型(类,字符串等)打开自动完成。我使用这两个组件,我可以说这是Silex / Pimple自动完成的好选择。

答案 5 :(得分:0)

Pimple只介绍容器构建器原理。如果您了解它,则不再需要Pimple:


class Container
{
    private $shared = array();

    public function getService() {
        return new Service(
            this->getFirstDependence(),
            this->getSecondDependence()
        );
    }

    protected function getFirstDependence() {
        return new FirstDependence(
            this->getSecondDependence()
        );
    }

    protected function getSecondDependence() {
        return isset($this->shared[__METHOD__]) ? $this->shared[__METHOD__] : $this->shared[__METHOD__] =
        new SecondDependence(
        );
    }
}

这样,Pimple不会隐藏混合$ c ['some key']中的对象类型。编辑容器时,您会有自动填充建议。 Phpstorm能够从您的代码中自动解析方法返回类型。你会有明确的容器。您可以覆盖容器:


class TestContainer extends Container
{
    protected function getFirstDependence() {
        return new FirstDependenceMock(
        );
    }
}

说实话,用'编程'语言编写的容器是错误的方法。容器责任是将对象的初始化图形带到调用者。访问“编程语言”可以轻松地违反这一责任。用于配置依赖性的一些DSL更好。此外,大多数原始依赖信息(构造函数的参数类型提示)都被Pimple和sfDepenencyContainer忽略,使您的配置变得臃肿和脆弱。