Fester Bestertester
Quiero algunos comandos de terminal para mi aplicación Symfony2. he pasado por el ejemplo en el libro de cocina, pero no pude averiguar cómo acceder a mi configuración, mi administrador de entidades y mis entidades aquí. En el constructor, obtengo el contenedor (que debería darme acceso a configuraciones y entidades) usando
$this->container = $this->getContainer();
Pero esta llamada genera un error:
Error fatal: llamada a una función miembro getKernel() en un no objeto en /Users/fester/Sites/thinkblue/admintool/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php en la línea 38
Básicamente, en ContainerAwareCommand->getContainer() la llamada a
$this->getApplication()
devuelve NULL y no un objeto como se esperaba. Supongo que dejé algún paso importante por fuera, pero ¿cuál? ¿Y cómo finalmente podré usar mis configuraciones y entidades?
Mate
Creo que no debería recuperar el contenedor en el constructor directamente. En su lugar, recupérelo en el configure
método o en el execute
método. En mi caso, obtengo mi administrador de entidad justo al comienzo de la execute
método como este y todo funciona bien (probado con Symfony 2.1).
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManager = $this->getContainer()->get('doctrine')->getEntityManager();
// Code here
}
Creo que la creación de instancias del objeto de la aplicación aún no se ha realizado cuando está llamando getContainer
en su constructor que da como resultado este error. El error viene del getContainer
método que intenta hacer:
$this->container = $this->getApplication()->getKernel()->getContainer();
Ya que getApplication
aún no es un objeto, obtiene un error que dice o está llamando a un método getKernel
en un no-objeto.
Actualizar: En la versión más nueva de Symfony, getEntityManager
ha quedado en desuso (y podría haberse eliminado por completo ahora). Usar $entityManager = $this->getContainer()->get('doctrine')->getManager();
en cambio. Gracias a Chausser por señalarlo.
Actualización 2: En Symfony 4, se puede usar el cableado automático para reducir la cantidad de código necesario.
Crear un __constructor
con un EntityManagerInterface
variable. Esta variable será accesible en el resto de sus comandos. Esto sigue el esquema de inyección de dependencia de cableado automático.
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();
}
}
Créditos a @profm2 por proporcionar el comentario y el código de muestra.
-
Con la última versión ->getEntityManager(); ahora está en desuso a favor de ->getManager();
– Perseguir
27 de junio de 2013 a las 5:21
-
Recuerde extender ContainerAwareCommand en lugar de Command para acceder al método getContainer()
– esmoquin
18 de marzo de 2014 a las 12:28
-
En Symfony 4, crea un __constructor con una variable EntityManagerInterface. Esta variable será accesible en el resto de sus comandos. Esto sigue el esquema de autowiring/dependencyInjection.
– profem2
16 de enero de 2018 a las 19:59
-
Un pequeño apéndice: no te olvides de poner el
use Doctrine\ORM\EntityManagerInterface;
en la cima– muc
29 ago 2018 a las 18:50
-
ContainerAwareCommand está en desuso desde 4.2. ¿Alguna solución para usar más adelante?
– Isengo
13 de diciembre de 2018 a las 13:51
extiende su clase de comando desde ContainerAwareCommand en lugar de Command
class YourCmdCommand extends ContainerAwareCommand
y obtenga un administrador de entidades como este:
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
-
ContainerAwareCommand está en desuso desde 4.2. ¿Alguna solución para usar más adelante?
– Isengo
13 de diciembre de 2018 a las 13:52
-
@Isengo muestra otras respuestas más recientes porque mi sugerencia es demasiado antigua
– stloc
14 de diciembre de 2018 a las 19:54
-
@Isengo A partir de Symfony 4.2, puede inyectar Doctrine\ORM\EntityManagerInterface en Command.
– vim
31 de enero de 2019 a las 11:54
Sé que la respuesta de Matt resolvió la pregunta, pero si tiene más de un administrador de entidades, puede usar esto:
Hacer modelo.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>
Luego cargue este archivo en su extensión DI
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('model.xml');
Entonces puedes usarlo en cualquier lugar. En el comando de la consola, ejecute:
$em = $this->getContainer()->get('EM_NAME.entity_manager');
y no olvides al final de:
$em->flush();
Ahora puede usarlo como argumento en otro servicio en services.yml:
services:
SOME_SERVICE:
class: %parameter.class%
arguments:
- @EM_NAME.entity_manager
Espero que esto ayude a alguien.
tengo el mismo error cuando (e intento acceder
getContainer()
dentro deMyCommand->execute()
pero aún obtengo el mismo error fatal. miCommandTest extends \PHPUnit_Framework_Testcase
y lo ejecuto a través dephpunit -c app src/CompanyName/MyBundle/Tests/Commands/MyCommandTest.php
¿Alguna idea de lo que puede estar mal?– Dimitri K.
25 de julio de 2014 a las 8:28