Как да получите автоматично довършване за контейнер с помощта на phpstorm и плъгин symfony2?

Използвам phpstorm. Когато разработвам приложение на symfony2, съм свикнал с плъгина на symfony2, предоставящ автоматично довършване за контейнерни услуги:

[пример за symfony2

Това предлага завършване и на върнатите обекти.

Има ли начин да накарате завършването на услугата да работи, когато използвате контейнерния компонент в PHP проект, различен от Symfony, който използва само части от компонентите на symfony2, т.е. контейнерния компонент?

Знам, че в настройките на 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]

Как мога да създам container.xml, който да бъде разбран от плъгина symfony2 и да ми предложи двете услуги redis и doctrine в контейнера?


person k0pernikus    schedule 26.08.2015    source източник


Отговори (2)


Този XML файл е създаден от ContainerBuilderDebugDumpPass компилаторът преминава в Symfony2 Standard Edition и можете да видите, че използва XmlDumper, за да създадете файла.

person Yassine Guedidi    schedule 26.08.2015

Създадох команда:

<?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

в дефиницията на контейнера.

След това трябваше да променя името на класа на услугата доктрина. Изглежда, че всичко става там, но този низ е това, което добавките на symfony2 използват за откриване на услугата.

След това получих автоматично довършване за контейнерни услуги.

Трябва да се отбележи, че свойството клас в services.yml също е важно. Тъй като обектът, който всъщност получавам от container->get('doctrine'), е екземпляр на EntityManager, трябва да дефинирам този начин, за да получа автоматично довършване:

doctrine:
    class: Doctrine\ORM\EntityManager
    factory: [\App\Database\DoctrineService, getDoctrine]
person k0pernikus    schedule 26.08.2015
comment
Не трябва директно да използвате повторно пропуска на компилатора, можете просто да копирате и поставите дефиницията му във вашата команда. Тогава вече няма да зависиш от FrameworkBundle. - person Yassine Guedidi; 27.08.2015
comment
@YassineGuedidi Бихте ли били по-конкретни? Не знам какво имаш предвид. - person k0pernikus; 27.08.2015
comment
Вместо да създадете ContainerBuilderDebugDumpPass и след това да извикате функцията на процеса, просто копирайте/поставете дефиницията на функцията на процеса във функцията за изпълнение на вашия команден клас. - person Yassine Guedidi; 27.08.2015
comment
@YassineGuedidi Това би нарушило указанието да не се повтаряте. - person k0pernikus; 27.08.2015
comment
Не. Това не е използването на пропуск на компилатор, трябва да се използва с компилатор. Това е доста прост код. Зависете от FrameworkBundle само за това не си струва. - person Yassine Guedidi; 27.08.2015
comment
Ако предпочитате, заменете копиране/поставяне, като използвате същата логика като :) - person Yassine Guedidi; 27.08.2015