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

Bla*_*ise 64 php ide dependency-injection phpstorm

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

我看了Bucket,PimplesfServiceContainer,进行了一些测试,真的很欣赏DIC的工作方式.因为它的简单性和原始力量,我可能会选择Pimple.如果我没有这个问题:

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

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

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

OZ_*_*OZ_ 57

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

/** @var YourClassType $mailer */
$mailer = $container['mailer'];
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我认为诀窍是你要在容器中定义一次,而不是每次使用它 - 用phpdoc乱丢代码. (6认同)
  • netbeans不支持这个例子(认为它应该),但确实从phpdoc标签中获取类型. (3认同)
  • @hakre:它也适用于普通变量;) (2认同)

Dav*_*ess 44

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

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

/**
 * My container. It contains things. Duh.
 *
 * @property MyService $service
 * @property MyDao $dao
 */
class MyContainer extends Container { }
Run Code Online (Sandbox Code Playgroud)

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

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

顺便说一句,对于类型提示直列变量@var在NetBeans中,你需要使用/*带有一个星号.这不是文档块注释,也不适用于/**//.此外,名称出现在类型之前.

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

  • 关于单个星号的提示+1.双星号正在为我打破它.谢谢. (3认同)

hak*_*kre 13

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

Netbeans/Phpstorm/PDT/ZendStudio示例

/* @var $mailer MailerInterface */
$mailer = $sc->mailer
Run Code Online (Sandbox Code Playgroud)

代码完成再次开始工作$mailer.

对于PDT来说,重要的是:

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

备选注释变体

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

/** @var $mailer MailerInterface */
Run Code Online (Sandbox Code Playgroud)

PHPDoc兼容性

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

/** @var MailerInterface $mailer  */
Run Code Online (Sandbox Code Playgroud)

该文档通常用于类变量(@var - 记录类变量的数据类型).然后,PHPDoc在评论之后缺少类变量的定义,这涉及QA的负担.

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

  • 第二个例子显示了phpdoc-comment的错误使用.类型应仅为BEFORE变量.它只是为了支持旧代码.http://manual.phpdoc.org/HTMLframesConverter/default/phpDocumentor/tutorial_tags.var.pkg.html (2认同)

小智 7

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

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