PHPStorm自动完成数组键(动态插入)

PHPStorm自动完成数组键(动态插入),php,dependency-injection,inversion-of-control,phpstorm,pimple,Php,Dependency Injection,Inversion Of Control,Phpstorm,Pimple,我正在使用Pimple dependency injector,每次使用容器中的依赖项时,我都会情不自禁地仔细检查用于获取依赖项的键的拼写: $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... P

我正在使用Pimple dependency injector,每次使用容器中的依赖项时,我都会情不自禁地仔细检查用于获取依赖项的键的拼写:

$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声明之前在与$ioc声明相同的文件中包含/**@var array | Pimple$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"];
   }
}

我目前使用PhpStorm的DynamicReturnTypePlugin,并在我的
dynamicReturnTypeMeta.json
中对其进行了以下配置:

{
    "methodCalls": [
        {
            "class": "\\MyOwnWrapperOfDIContainer",
            "method": "get",
            "position": 0
        },
        {
            "class": "\\Pimple\\Container",
            "method": "offsetGet",
            "position": 0
        }
    ]
}

此配置意味着以下内容:每当在代码中,我使用任何类型的变量<代码> pimple \容器>代码>作为一个数组(这将调用它的代码> ARAYAccess::OffStGET< < /Case>方法),然后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();
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();
或者你必须找到解决问题的其他方法

编辑1

也考虑这篇文章:

编辑2 这个插件呢

编辑3 此外,还可以像这样解决上述问题:

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();
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
        }
    ]
}
将文件“.phpstorm.meta.php”放入存储库的根目录中。.phpstorm.meta.php文件的内容:

<?php
namespace PHPSTORM_META {
    override( \Container::get(0), map([]));
}


现在您可以使用所有类方法的自动完成。

但是。。。PhpStorm支持完成数组键,因此它应该可以工作(具体取决于您使用它的方式):。可能(只是可能——我自己没有测试过)它不起作用,因为
$ioc
不是纯数组,而是带有ArrayIterator(或类似)接口的对象?这正是它不起作用的原因。PHPStorm甚至会抛出一个警告(取决于intellisense设置),表示它无法跟踪动态添加的属性。这是因为
ArrayAccess
。。好啊目前PhpStorm对这类东西的支持非常有限()。只是一个想法(不确定它将如何工作)——如果您通过PHPDoc添加typehint,说明此变量既是普通数组又是Pimple实例,该怎么办?e、 g.
/**@var array | Pimple$ioc*/
$ioc
初始化之前。之后要关注的另一个问题是:1)和2)在任何情况下——您能否提供一些简单的代码示例,我可以对其进行一些测试——当然,如果上述建议不起作用的话。