I got an annoying problem when I call this in a controller (ClientDomainController) :
$this->getDoctrine()->getManager();
I got this error :
Call to a member function has() on null
I looked the stack trace and see that :
$this->container is null
My controller extends from the Symfony Controller component :
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
The funny thing is that in an other controller (HomeController) I make the exact same things :
And this without any error.
The only one difference between the HomeController and the ClientDomainController is that the second one is a service. So I wrote it in the services.yml file :
services:
client_domain:
class: AppBundle\Controller\ClientDomainController
Finally I tested many things like creating a constructor to my controller and adding this to the services.yml file (things that a never did to the functional one) :
arguments: [ 'doctrine.orm.entity_manager' ]
When you register your controller as a service, then, Symfony creates it just like you tell it to do.
So the difference is that although your controller implements ContainerAwareInterface
(via extending Controller
class), in the end nobody calls setContainer
method to utilize this interface and set $container
's value. You have to do it manually in you services.yml config like:
calls:
- [ setContainer, [ @service_container ] ]
But this is not the best solution
Registering your controllers as services is good in general. It makes them more testable and maintainable.
But this is true as long as you stick to the good rules of OOP . In this case when you pass whole container it means that:
In short words, dependences should be passed via contrustor as you did in the end or you could use action-based dependency injection when a dependency is used only in this particular action.
Actually best solution would be even not to extend base Controller
class to make you controllers framework independent.
Your controller should be like this:
class HelperController extends Controller
{
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* HelperController constructor.
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
}
and in config file (in my case xml)
<service id="xxx.helper_controller" class="xxx\EspacePROBundle\Controller\HelperController">
<argument type="service" id="service_container" />
</service>
I hope it help.
As stated in Jakub Matczak's answer the DI container for the controller is not set.
Alternatively to adding the calls
section in your services.yml you can call setContainer
in the constructer of the class where you want to use the controller.
use App\Controller\MyController;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MyClass {
/**
* The injected controller
* @var MyController
*/
protected $my_controller;
public function __construct(MyController $my_controller, ContainerInterface $container) {
$this->my_controller = $my_controller;
$this->my_controller->setContainer($container);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.