64 votes

Comment faire en sorte que mon IDE PHP comprenne les conteneurs d'injection de dépendance?

Situation actuelle: j'ai des dépendances dans mon projet qui me résoudre à l'aide de l'injection de dépendance. Je veux prendre la prochaine étape logique à l'aide d'un conteneur d'injection de dépendance (DIC) pour faciliter la gestion de mes dépendances et paresseux-classes de charge.

J'ai regardé Seau, Bourgeon, et sfServiceContainer, a couru quelques tests et j'apprécie vraiment la façon dont DIC. Je serais probablement aller pour un Bouton en raison de sa simplicité et de puissance brute. Si je n'avais pas ce problème:

En raison de l'abstraction de la DIC, l'offre, l'IDE que j'utilise (PHPStorm) ne comprend plus ce qui se passe dans mon code. Il ne comprend pas que $container['mailer'] ou $sc->mailer est maintenant un objet de classe. J'ai aussi essayé Netbeans IDE: même problème.

C'est vraiment un problème pour moi parce que mon IDE devient inutile. Je ne veux pas de programme sans les conseils de code, l'auto-complétion et le refactoring lorsque vous traitez avec des classes. Et je ne veux pas que mon IDE pour trouver toutes sortes de faux positifs lors de la validation du code.

Donc ma question est: quelqu'un A résolu ce problème et trouvé une solution?

57voto

OZ_ Points 7398

Vous pouvez définir la classe de la variable 'manuellement':

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

Dans PhpStorm (et selon les normes ), utilisez deux astérisques et écrivez DataType avant le nom de la variable.
Vous pouvez écrire DataType sans nom de variable (mais pas nom sans DataType).

44voto

David Harkness Points 16674

Alors que vous pouvez certainement dire à votre IDE le type de l'objet sorti de votre conteneur de tous les temps d'accès, il est préférable de le faire une fois. Les deux solutions suivantes impliquent sous-classement du conteneur. Je viens de commencer en utilisant le Bouton qui recommande de faire cela de toute façon.

Pour les conteneurs qui utilisent les membres de l'instance accessible avec -> vous pouvez dire à votre IDE de ce type qu'ils détiennent. C'est génial parce que ça ne donne lieu à aucune analyse supplémentaire lorsque le code est exécuté--seulement l'IDE est gêné par elle.

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

Pour Boutons et autres récipients qui agissent comme des tableaux, vous pouvez créer des fonctions d'accesseur pour les objets de plus haut niveau que vous aurez besoin. Même si cela signifie que plus l'analyse lorsque le conteneur est créé, il doit être fait une fois et conservé dans de l'APC. Je préfère largement une méthode d'accès au tableau de toute façon depuis qu'il est facile d'oublier clé du tableau à l'intérieur d'une auto-complété méthode.

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

BTW, pour type-hinting inline variables @var dans NetBeans, vous devez utiliser /* avec un astérisque. C'est pas un doc-bloc de commentaire et ne fonctionne pas avec /** ou //. Aussi, le nom vient avant que le type.

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

13voto

hakre Points 102271

Que l'IDE n'a pas exectue le code, ils ne connaissent pas et ont besoin de l'aide du formulaire que vous. Je sais que cela fonctionne pour Eclipse et d'autres IDEs ainsi: Indicateur de type de la variable.

Netbeans / Phpstorm / PDT / ZendStudio Exemple

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

Code complet commence à travailler à nouveau sur $mailer.

Pour les HAP, il est important que:

  1. Le commentaire commence avec un * seulement.
  2. D'abord le nom de la variable, que l'astuce.

Alternative Commentaire Variantes

Comme il a été l'objet de beaucoup de discussion, il peut différer entre les IDEs. Cependant, la plupart des IDEs de soutien variable conseils de code en ligne variables de la manière ci-dessus. Donc, en fonction de l'IDE c'est peut-être écrit de manière différente, mais similaire, comme ici avec deux astérisques devant:

/** @var $mailer MailerInterface */

PHPDoc compatibilité

PHPDoc analyseurs peuvent avoir un problème si vous imiter la classe var doc-commentaire de code en ligne de la manière suivante:

/** @var MailerInterface $mailer  */

Que la documentation est normalement utilisé pour les variables de classe (@var - Document le type de données d'une variable de classe). PHPDoc est alors disparu de la définition de la variable de classe après le commentaire qui implique une charge pour l'assurance qualité.

Cependant, certaines IDEs offrira code d'achèvement pour de simples variables ainsi lorsqu'il est écrit en PHPDoc clas-variable de style. Je ne sais pas si cela a des effets secondaires pour le code-achèvement de la classe courante, puis en tant que nouveau membre peut être présenté (qui en fait n'existe pas.

0voto

palex Points 11

Bouton juste place conteneur générateur de principe. Si vous comprenez cela, vous n'avez pas besoin de Bouton plus:


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(
        );
    }
}

De cette façon, le Bouton ne cache pas le type de l'objet du mixed $c['clés']. Vous auriez des suggestions de saisie semi-automatique lors de l'édition de votre conteneur. Phpstorm est capable de autoresolve méthode de type de retour à partir de votre code. Et vous auriez récipient transparent. Vous pouvez toujours remplacer le conteneur:


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

Pour être honnête conteneur écrit 'programmation' lanuage est pas la voie à suivre. Conteneur responsabilité est d'apporter initialisé graphe d'objets à l'appelant. Avoir accès à la programmation de la langue " permet de violer cette responsabilité avec facile. Certains DSL pour la configuration de la dépendance, c'est mieux. En outre, la plupart d'origine des informations sur la dépendance (argument typehints de constructeurs) est tout simplement ignorés par Bouton et sfDepenencyContainer faire de votre configuration lourd et fragile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X