Как сделать так, чтобы моя PHP IDE понимала контейнеры для инъекций зависимостей?



текущая ситуация: у меня есть зависимости в моем проекте, которые я решаю с помощью инъекции зависимостей. Я хочу сделать следующий логический шаг, используя контейнер инъекций зависимостей (DIC), чтобы облегчить управление моими зависимостями и классами ленивой загрузки.



Я посмотрел на ведра,прыщ и sfServiceContainer, провел некоторый тест и действительно оценил, как работает DIC. Я бы, наверное, пошел на прыщ из-за его простоты и сырой силы. Если бы у меня не было этой проблемы:



из-за абстракции, которую предлагает DIC, IDE, которую я использую (PHPStorm), больше не понимает, что происходит в моем коде. Он не понимает, что $container['mailer'] или $sc->mailer содержит объект класса. Я также попробовал IDE Netbeans: та же проблема.



Это действительно проблема для меня, потому что моя IDE становится бесполезной. Я не хочу программировать без подсказок кода, автозаполнения и инструментов рефакторинга при работе с классами. и я не хочу, чтобы моя IDE находила все виды ложных срабатываний при проверке кода.



Итак, мой вопрос: кто-нибудь сталкивался с этой проблемой и нашел решение?

697   6  

6 ответов:

вы можете определить класс переменной 'вручную':

/** @var YourClassType $mailer */
$mailer = $container['mailer'];

в PhpStorm (и стандарты), используйте две звездочки и запишите тип данных перед именем переменной.

вы можете написать тип данных без имени переменной (но не имя без типа данных).

в то время как вы можете, конечно, сказать своей IDE тип объекта, вытащенного из вашего контейнера каждый раз, когда вы получаете доступ к нему, лучше сделать это один раз. Оба из следующих решений включают подклассы контейнера. Я только начал использовать прыщ, который рекомендует делать это в любом случае.

для контейнеров, использующих члены экземпляра, доступ к которым осуществляется с помощью -> или с помощью магии __get метод, вы можете сказать вашей IDE, какой тип они держат. Это здорово, потому что не требует никакого дополнительного синтаксического анализа при запуске кода-только IDE беспокоит его.

/**
 * My container. It contains things. Duh.
 *
 * @property MyService $service
 * @property MyDao $dao
 */
class MyContainer extends Container { }

для Pimple и других контейнеров, которые действуют как массивы, вы можете создавать функции доступа для объектов верхнего уровня, которые вам понадобятся. Хотя это означает больше разбора при создании контейнера, это должно быть сделано один раз и сохранено в APC. Я чрезвычайно предпочитаю метод доступа к массиву любом случае, поскольку он помещает легк-к-забыть ключ внутри авто-завершения метод.

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

кстати, для типа-намекая встроенные переменные с @var в NetBeans необходимо использовать /* С одна звездочка. Это не комментарий doc-блока и не работает с /** или //. Кроме того, имя стоит перед типом.

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

поскольку IDE не выполняют код, они не знают и нуждаются в некоторой помощи. Я знаю, что это работает для Eclipse и других IDE: подсказка типа переменной.

Netbeans / Phpstorm / PDT / Zendstudio пример

/* @var $mailer MailerInterface */
$mailer = $sc->mailer

Code complete снова начинает работать на $mailer.

для ФДТ важно, чтобы:

  1. комментарий начинается с * только.
  2. сначала имя переменной, чем намек.

Альтернативные Варианты Комментария

как это было предметом большого обсуждения, он может отличаться между IDE. Однако большинство IDE поддерживают переменные, намекающие на встроенные переменные кода выше. Поэтому в зависимости от IDE это может быть написано по-разному, но похоже, как здесь с двумя звездочками спереди:

/** @var $mailer MailerInterface */

совместимость с PHPDoc

Парсеры PHPDoc могут иметь проблемы, если вы имитируете класс var doc-комментарий для встроенного кода так:

/** @var MailerInterface $mailer  */

эта документация обычно используется для переменных класса ( @var-документ тип данных переменной класса). PHPDoc затем отсутствует определение переменной класса после комментария, который включает в себя бремя для QA.

однако некоторые IDE будут предлагать завершение кода для простых переменных, а также при написании в стиле PHPDoc clas-variable. Я не знаю, если это имеет побочные эффекты для код-завершение текущего класса, то как новый член может быть введен, что на самом деле не существует.

для тех, кто пришел сюда из гугла.

PHPStorm фактически предоставляет способ решить эту проблему вместо того, чтобы писать PHPDocs снова и снова - создание и настройка в сторону описано здесь выигрыш работает плавно автозаполнения и проверки типа.

Я знаю, что вопрос только о DIC, но есть Silex Pimple Dumper поставщик услуг, который сбрасывает контейнер в файл json. Тот же автор писал плагин для PHPStorm который может прочитать этот файл и открыть автозаполнение с именами служб и его типом (класс, строка и т. д.). Я использую эти два компонента, и я могу сказать, что это хорошие варианты для автоматического завершения для Silex/Pimple.

прыщ просто ввести контейнер builder principe. Если вы это понимаете, вам больше не нужен прыщ:


class Container
{
    private $shared = array();

    public function getService() {
        return new Service(
            this->getFirstDependence(),
            this->getSecondDependence()
        );
    }

    protected function getFirstDependence() {
        return new FirstDependence(
            this->getSecondDependence()
        );
    }

    protected function getSecondDependence() {
        return isset($this->shared[__METHOD__]) ? $this->shared[__METHOD__] : $this->shared[__METHOD__] =
        new SecondDependence(
        );
    }
}

таким образом, Pimple не скрывает тип объекта в mixed $c['some key']. У вас будут предложения по автозаполнению при редактировании вашего контейнера. Phpstorm может автоматически решить тип возврата метода из вашего кода. И у вас будет прозрачный контейнер. Вы можете когда-нибудь переопределить контейнер:


class TestContainer extends Container
{
    protected function getFirstDependence() {
        return new FirstDependenceMock(
        );
    }
}

чтобы быть честным контейнер написан в "Программирование" lanuage это неправильный путь. Ответственность контейнера заключается в том, чтобы привести инициализированный граф объектов к вызывающему. Наличие доступа к "языку программирования" позволяет легко нарушать эту ответственность. Некоторые DSL для настройки зависимости лучше. Более того, большая часть исходной информации о зависимостях (типы аргументов конструкторов) просто игнорируется Pimple и sfDepenencyContainer, что делает вашу конфигурацию раздутой и хрупкой.

Comments

    Ничего не найдено.