Hola. Siguiendo el tutorial de cómo definir un controlador como servicio me encuentro con este error:
services: fos_user.doctrine_registry: alias: doctrine fichada: class: AppBundle\FichadaBundle\Controller\FichadaController
Probé las dos formas de llamar al controlador import desde este controller:
public function importarfichadaAction() { // $fichada = $this->get('fichada'); // $fichada->importAction(); $this->forward('fichada:importAction'); }
De las dos formas me da el mismo error al intentar cargar el entity manager en el otro controlador
Error: Call to a member function has() on null
El error sale justo al tratar de correr esta línea:
$em = $this->getDoctrine()->getManager();
Respuestas
Antes de responder a tu pregunta, me gustaría decirte que no se recomienda el uso de los controladores como servicios. El propio creador de Symfony dice que es una muy mala práctica y que nunca habría que usar controladores como servicios.
Respondiendo a tu pregunta, uno de los muchos problemas que te vas a encontrar al usar controladores como servicios es que no tienes acceso preconfigurado a ninguno de los servicios que utilizas dentro del controlador.
Cuando haces $this->getDoctrine()
en realidad estás obteniendo el servicio doctrine
del contenedor de servicios de Symfony. Antes de obtenerlo se hace un $this->has('doctrine')
y esa es la línea que te está fallando. Al usar el controlador como servicio, no tienes acceso ni a Doctrine ni al contenedor de servicios, por lo que el $this->has(...)
falla.
La solución consiste en inyectar a mano todos los servicios que vayas a necesitar, como por ejemplo doctrine
. Así que en la definición de tu controlador-servicio tendrías que hacer lo siguiente:
services: fos_user.doctrine_registry: alias: doctrine fichada: class: AppBundle\FichadaBundle\Controller\FichadaController arguments: ['@doctrine']
Después tienes que añadir un __construct()
en el controlador para obtener el servicio doctrine
que has inyectado. Como ves, los controladores-servicio te hacen trabajar mucho más y sus supuestas ventajas son muy discutibles. Si puedes, olvídate de ellos para siempre.
@javiereguiluz
Gracias por la respuesta, buscando en google recomendaban usar servicios y otros no...
lo que intentaba hacer era reutilizar un método de un controlador en otro para no duplicar código, lo que puedo hacer es pasar esa lógica al modelo y reutilizarlo de ahí.
Esa seria la forma correcta de reutilizar código para no usar servicios ?
Saludos
@xub
Como dices, puedes pasar esa lógica al modelo. También podrías hacer un servicio sencillo y específico para esa lógica y que sea independiente del modelo y de los controladores.
@javiereguiluz
Hola,
En mi opinión, yo recomendaría hacer la lógica específica en una clase independiente y esa clase es la que convertirías en un servicio, ya teniendo eso inyectar ese servicio en los controladores.
Analizándolo bien, creo que es lo mismo que recomienda Javier.
Saludos
@miguelplazasr