2011-09-22 18 views
38

Voglio alcuni comandi del terminale per l'applicazione Symfony2. Ho esaminato lo example in the cookbook, ma non sono riuscito a scoprire come accedere alle mie impostazioni, al mio gestore di entità e alle mie entità qui. Nel costruttore, ottengo il contenitore (che mi dovrebbe produrre l'accesso alle impostazioni e alle entità) utilizzandoCome utilizzare i miei Entity Manager ed Entity Manager nel comando console di Symfony 2?

$this->container = $this->getContainer(); 

Ma questa chiamata genera un errore:

Fatal error: Call to a member function getKernel() on a non-object in /Users/fester/Sites/thinkblue/admintool/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php on line 38

In sostanza, in ContainerAwareCommand-> getContainer() la chiamata a

$this->getApplication() 

restituisce NULL e non un oggetto come previsto. Immagino di aver lasciato un passo importante, ma quale? E come potrò finalmente usare le mie impostazioni ed entità?

+0

sto avendo lo stesso errore quando (e tento di accedere 'getContainer() 'all'interno di' MyCommand-> execute() 'ma ottiene lo stesso errore fatale. il mio' CommandTest estende \ PHPUnit_Framework_Testcase' e ​​lo eseguo tramite 'phpunit -c app src/CompanyName/MyBundle/Tests/Commands/MyCommandTest.php' Qualche idea su cosa può essere sbagliato? –

risposta

71

Penso che non si debba recuperare direttamente il contenitore nel costruttore. Invece, recuperarlo nel metodo configure o nel metodo execute. Nel mio caso, ottengo il mio gestore di entità proprio all'inizio del metodo execute in questo modo e tutto funziona correttamente (testato con Symfony 2.1).

protected function execute(InputInterface $input, OutputInterface $output) 
{ 
    $entityManager = $this->getContainer()->get('doctrine')->getEntityManager(); 

    // Code here 
} 

penso che l'istanza dell'oggetto applicazione non è ancora finito, quando si sta chiamando getContainer nel costruttore che danno luogo a questo errore. L'errore deriva dal metodo getContainer tyring fare:

$this->container = $this->getApplication()->getKernel()->getContainer(); 

Dal getApplication non è ancora un oggetto, si ottiene l'un errore che dice o stanno chiamando un metodo getKernel su un non-oggetto.

Aggiornamento: nella versione più recente di Symfony, getEntityManager è stato deprecato (e avrebbe potuto essere rimosso del tutto ormai). Utilizzare invece $entityManager = $this->getContainer()->get('doctrine')->getManager();. Grazie a Chausser per indicarlo.

Aggiornamento 2: In Symfony 4, è possibile utilizzare il cablaggio automatico per ridurre la quantità di codice necessaria.

Creare un __constructor con una variabile EntityManagerInterface. Questa variabile sarà accessibile nel resto dei tuoi comandi. Questo segue lo schema di iniezione delle dipendenze del cablaggio automatico.

class UserCommand extends ContainerAwareCommand { 
    private $em; 

    public function __construct(?string $name = null, EntityManagerInterface $em) { 
    parent::__construct($name); 

    $this->em = $em; 
    } 

    protected function configure() { 
    **name, desc, help code here** 
    } 

    protected function execute(InputInterface $input, OutputInterface $output) { 
    $this->em->getRepository('App:Table')->findAll(); 
    } 
} 

Crediti a @ profm2 per fornire il commento e il codice di esempio.

+0

Ho avuto quello pensato o già, ma come newb, non ho potuto rispondere alla mia domanda. Non è possibile ottenere il contenitore nel costruttore, poiché non esiste ancora. Funziona tutto magnificamente se si recupera il contenitore nel metodo di esecuzione. Successivamente, puoi accedere alle tue Entità nel modo consueto: $ myEntities = $ em-> getRepository ('Acme \ DemoBundle: Myentity') -> findAll(); –

+10

Con l'ultima versione -> getEntityManager(); è ora deprecato a favore di -> getManager(); – Chausser

+1

Ricordare di estendere ContainerAwareCommand anziché Command per accedere al metodo getContainer() – tuxone

4

So che la risposta di Matt risolto la questione, ma se hai più di un gestore di entità, è possibile utilizzare questo:

Marchio model.xml con:

<?xml version="1.0" encoding="UTF-8" ?> 

<container xmlns="http://symfony.com/schema/dic/services" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://symfony.com/schema/dic/services   http://symfony.com/schema/dic/services/services-1.0.xsd"> 

<services> 
    <service id="EM_NAME.entity_manager" alias="doctrine.orm.entity_manager" /> 
</services> 
</container> 

Poi caricare questo file nell'estensione DI

$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 
$loader->load('model.xml'); 

Quindi è possibile utilizzarlo ovunque. In Command Console eseguire:

$em = $this->getContainer()->get('EM_NAME.entity_manager'); 

e non dimenticare alla fine:

$em->flush(); 

È ora possibile utilizzare come un argomento a un altro servizio in services.yml:

services: 
    SOME_SERVICE: 
     class: %parameter.class% 
     arguments: 
      - @EM_NAME.entity_manager 

Spero che questo aiuti qualcuno.

8

estende la classe di comando da ContainerAwareCommand invece di Command

class YourCmdCommand extends ContainerAwareCommand 

e ottenere gestore di entità simile a questo:

$em = $this->getContainer()->get('doctrine.orm.entity_manager'); 
Problemi correlati