2011-08-27 10 views
15

Sto usando PHP Storm come IDE, ma credo che altri IDE come Netbeans avranno lo stesso problema che spiegherò di seguito.Preservare le capacità di completamento automatico con Symfony2 Dipendenza iniezione

Quando si utilizza un framework come Symfony2, abbiamo aggiunto il meraviglioso mondo di Dependency Injection. Così gli oggetti possono semplicemente essere istanziati utilizzando il codice come il seguente frammento:

$myThingy = $this->get('some_cool_service'); 

Questo è molto utile, in quanto gli oggetti sono già configurati in precedenza. L'unico problema è che il completamento automatico si interrompe interamente in praticamente qualsiasi IDE PHP, poiché l'IDE non sa quale tipo restituisce il metodo get().

C'è un modo per preservare il completamento automatico? La creazione di un'estensione di Controller sarebbe la risposta? Ad esempio:

class MyController extends Controller { 
    /** 
    * @return \MyNamespace\CoolService 
    */ 
    public getSomeCoolService() { 
     return new CoolService(); 
    } 
} 

e quindi per i controller dell'applicazione, specificare MyController come classe base anziché Controller?

Cosa ne pensi di utilizzare una classe Factory o altri metodi possibili?

+0

Il problema è che non sa che è un oggetto o che non sa che è un oggetto di una classe specifica? Se è il primo, non puoi semplicemente lanciare $ myThingy come oggetto? '$ myThingy = (oggetto) $ this-> get ('some_cool_service');' – DaveRandom

+0

Vero, ma anche il casting su un oggetto lascerà l'IDE senza tracce su quale sia il tipo di classe delle istanze, cioè ... ancora senza auto -completamento tristemente. :( –

+0

Stesse cose che avevo: http://stackoverflow.com/questions/21936380/best-practise-including-code-completion-in-zf2, stesse soluzioni ma tutti hanno bisogno di lavoro extra – Gizzmo

risposta

15

E 'più coinvolgente, ma è ancora possibile farlo con Eclipse PDT:

$myThingy = $this->get('some_cool_service'); 
/* @var $myThingy \MyNamespace\CoolService */ 

UPDATE: L'esempio a this page mostra si può anche utilizzare il contrario con PhpStorm:

$myThingy = $this->get('some_cool_service'); 
/* @var \MyNamespace\CoolService $myThingy */ 
+1

Questo non ha mai funzionato nel mio Eclipse per qualche motivo: – gilden

+0

@gilden: sono abituato a farlo senza spazi dei nomi, non sono sicuro al 100% che funzioni, ma se sicuramente lo dovessi ... – greg0ire

+0

Ho appena provato di nuovo e sì ... non funziona per me. Posso Ctrl + clic sull'annotazione per aprire il file corrent però. Mi piacerebbe davvero che funzionasse – gilden

7

Si potrebbe definire le proprietà private nei tuoi controller

class MyController extends Controller 
{ 
    /** 
    * @var \Namespace\To\SomeCoolService; 
    */ 
    private $my_service; 

    public function myAction() 
    { 
     $this->my_service = $this->get('some_cool_service'); 
     /** 
     * enjoy your autocompletion :) 
     */ 
    } 
} 
+0

Questo sembra un inizio, sì. –

+0

In questo modo non puoi sapere nel codice se '$ this-> my_service' è già stato avviato. Vorrei utilizzare questo approccio solo con l'iniezione del costruttore. –

+0

@barius Sì, ho trovato l'approccio migliore per usare semplicemente i getter e fare il mio suggerimento qui per i controller. – gilden

1

Io uso Komodo Studio e taggare le variabili con @var, anche all'interno dei metodi, mantiene il completamento automatico per me.

namespace MyProject\MyBundle\Controller; 

use Symfony\Component\DependencyInjection\ContainerAware; 
use Symfony\Component\HttpFoundation\Request; 

class WelcomeController extends ContainerAware 
{ 
    public function indexAction() 
    { 
     /*@var Request*/$request = $this->container->get('request'); 
     $request->[autocomplete hint list appears here] 
    } 
} 
0

lavorare con NetBeans IDE 7.1.2 PHP

+0

sì funziona così:/* @var $ em \ Doctrine \ ORM \ EntityManager */ – ivoba

6

Io uso classe Controller base per bundle. È necessario annotare il metodo di ritorno. Almeno questo funziona su Eclipse.

Non mi piace/* var ... * /, perché diventa troppo codice. Non mi piacciono le proprietà private, perché si può presupporre erroneamente che i servizi siano già stati caricati.

+0

D'accordo su questa risposta, ho trovato che sia la soluzione più pulita per i casi in cui è necessaria la dipendenza nella classe più di 1 tempo. – Inoryy