我正在使用Pimple依赖注入器,每次我使用容器中的依赖项时,我都忍不住要仔细检查用于获取依赖项的键的拼写:
$ioc = new Pimple();
// 1. Define some object
$ioc["some-key"] = $ioc->share(function($c){ /* ... */});
// 2. Use it
$ioc["som... // Open config file and check spelling...
PHPStorm 是否有某种方法可以查找这些属性并提供自动完成功能?我考虑过使用像
这样的东西来定义所有这些键define('SOME_KEY', 'some-key');
// ...
$ioc[SOME_KEY] = $ioc->share(/* ... */);
但我想知道是否有更好的方法。
修改
以下是一些示例代码:
// project_root/library/App/Injector/Ioc.php
require_once "Pimple.php";
/** @var array|Pimple $ioc */
$ioc = new Pimple();
$ioc["version"] = "1.0.1650.63";
$ioc["location-service"] = $ioc->share(function ($c) {
return new Application_Service_Location();
}
);
事实证明,无论是否在$ ioc声明中包含/ ** @var数组| Pimple $ ioc * /,在同一个文件中,$ ioc是字符串自动完成工作正常声明。但是,由于我使用的是Zend Framework,我通常会使用$ ioc:
// project_root/Application/Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
protected function _initInjector() {
$ioc = null;
require_once LIBRARY_PATH . "/MFM/Injector/ioc.php";
Zend_Registry::set("ioc", $ioc);
}
}
// project_root/Application/Controllers/SomeController.php
class Application_Controller_SomeController extends Zend_Controller_Action {
public function IndexAction() {
/** @var Pimple $ioc */
$ioc = Zend_Registry::get("ioc");
// No IDE assistance for the string "location-service"
$service = $ioc["location-service"];
}
}
答案 0 :(得分:2)
我目前使用 DynamicReturnTypePlugin 作为PhpStorm并在dynamicReturnTypeMeta.json
中对其进行了以下配置:
{
"methodCalls": [
{
"class": "\\MyOwnWrapperOfDIContainer",
"method": "get",
"position": 0
},
{
"class": "\\Pimple\\Container",
"method": "offsetGet",
"position": 0
}
]
}
此配置意味着以下内容:每当在代码I中使用类型Pimple\Container
的任何变量作为数组(这将调用其ArrayAccess::offsetGet
方法)时,PhpStorm应该考虑返回值是访问该数组时用作键的类型。一世。 E:
$c = new Pimple\Container;
$c['MyClass']->/*here autocompletion works*/methodOfMyClass();
我也以这种方式使用它:
$myClassInstance = MyOwnWrapperOfDIContainer::get(MyClass::class);
$myClassInstance->methodOfMyClass(); // autocompletion works here
唯一的问题是当你在Pimple容器中注册一些依赖项时,不是通过它们的类名,而是使用你想要的其他名称。例如,自动完成在以下情况下不起作用:
$c = new Pimple\Container;
$c['my-favourite-var'] = new MyClass(1);
$c[MyClass::class] = new MyClass(2);
$c['my-favourite-var']->/*here autocompletion doesn't work*/methodOfMyClass();
$c['MyClass']->/*here autocompletion works*/methodOfMyClass();
仍然可以像这样解决它:
class MyFavouriteVar extends MyClass;
$c[MyFavouriteVar::class] = new MyFavouriteVar(2);
// or even like this:
$c[MyFavouriteVar::class] = new MyClass(2);
$c[MyFavouriteVar::class]->/*now autocompletion works fine*/methodOfMyClass();
或者您必须找到问题的其他解决方案......
还要考虑这篇文章: http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata
和这个插件 https://github.com/Sorien/silex-idea-plugin
也可以解决上面提到的问题:
class MyPimple extends Pimple\Container
{
public function get($type, $desc = null) {
return $this[$type . (isset($desc) ? ':' . $desc : '')];
}
}
$c = new MyPimple;
$c[MyClass::class] = new MyClass('default');
$c[MyClass::class . ':' . 'my-special-value'] = new MyClass('special');
$c->get(MyClass::class, 'my-special-value')->/*autocompletion should work*/methodOfMyClass();
dynamicReturnTypeMeta.json
应该包含:
{
"methodCalls": [
{
"class": "\\MyPimple",
"method": "get",
"position": 0
}
]
}
答案 1 :(得分:0)
把文件" .phpstorm.meta.php"进入您的存储库的根目录。文件内容.phpstorm.meta.php:
<?php
namespace PHPSTORM_META {
override( \Container::get(0), map([]));
}
其中\ Container :: get - 获取某个对象的方法,例如:
\Container::get('My\Super')
或
\Container::get(My\Super::class)
现在您可以使用所有类方法的自动完成功能。