如何使用 phpstorm 和 symfony2 插件获得容器的自动补全?

How to get autocompletion for container using phpstorm and symfony2 plugin?

我用的是phpstorm。在开发 symfony2 应用程序时,我习惯于 symfony2 插件为容器服务提供自动完成功能:

[

这也提供了返回对象的完成。

在仅使用部分 symfony2 组件(即容器组件)的非 symfony PHP 项目中使用容器组件时,有没有办法让服务完成工作?

我知道在phpstorm的设置中:

Other Settings > Symfony2 Plugins > Container

我可以添加额外的 xml 容器文件,但我不知道它应该是什么样子。

如何创建这样的文件?

例如,我通过以下方式创建容器:

/**
 * @return ContainerBuilder
 * @todo Initialize the container on a more reasonable place
 */
private function createServiceContainer()
{
    $container = new ContainerBuilder();
    $loader = new YamlFileLoader($container, new FileLocator(ROOT_PATH . '/config'));
    $loader->load('services.yml');

    return $container;
}

我的 services.yml 看起来像这样:

services:
    redis:
        class: App\Framework\RedisService
    doctrine:
        class: DoctrineService
        factory: [\App\Database\DoctrineService, getDoctrine]

我如何创建一个 symfony2 插件可以理解的 container.xml 并在容器中为我提供两项服务 redisdoctrine

那个XML文件是由ContainerBuilderDebugDumpPass compiler pass in the Symfony2 Standard Edition, and you can see that it use the XmlDumper创建的文件。

我创建了一个命令:

<?php
namespace App\Command;

use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

/**
 * ContainerRefreshCommand
 **/
class ContainerRefreshCommand extends Command
{
    /**
     * Configures the current command.
     */
    protected function configure()
    {
        $this
            ->setName('container:refresh')
            ->setDescription('refreshes the container file for usage with phpstorm');
    }


    /**
     * @param InputInterface  $input
     * @param OutputInterface $output
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $container = new ContainerBuilder();


        $loader = new YamlFileLoader($container, new FileLocator(ROOT_PATH . '/config'));
        $loader->load('services.yml');

        $container->setParameter('debug.container.dump', ROOT_PATH . '/dev/appDevDebugProjectContainer.xml');
        $containerFile = new ContainerBuilderDebugDumpPass();

        $containerFile->process($container);
    }
}

然后我从我的项目根目录添加了文件:

./dev/appDevDebugProjectContainer.xml

在容器定义中。

然后我不得不更改 class 学说服务的名称。那里似乎有任何东西,但这个字符串是 symfony2 插件用来检测服务的。

然后我得到了容器服务的自动完成。

需要注意的是 services.yml 中的 class 属性 也很重要。由于我实际上通过 container->get('doctrine') 获得的对象是 EntityManager 的实例,因此我必须定义这种方式来获得自动完成:

doctrine:
    class: Doctrine\ORM\EntityManager
    factory: [\App\Database\DoctrineService, getDoctrine]