my constructor of my Controller looks like:
function __construct(){#
var_dump($this->get('translator'));
exit();
}
this will give a FatalErrorException: Error: Call to a member function get() on a non-object
. But why? If I use it inside a action it will work.
This is because Controller method get
needs the container
property. Controller extends ContainerAware which has a method setContainer
. This method let the property container
be aware of the Container.
Upon instanciation, no method are called, here is the workflow
$controller = new MyController($parameters);
$controller->setContainer($container);
Before calling __construct, controller has no property $container
public function __construct($parameters)
{
var_dump($this->container); // NULL
}
So, by calling $this->get()
you are doing
$this->get('translator');
// =
$this->container->get('translator');
// =
null->get('translator');
Hence the error.
If you need the validator, you'll have to ask it in your constructor (and respect the Law of Demeter).
To do so, you'll need to declare your controller as a service
services.yml
services:
my_controller:
class: Acme\FooBundle\Controller\MyController
arguments:
- "@translator"
calls:
- [ "setContainer", [ "@service_container" ] ]
routing.yml
bar_route:
path: /bar
defaults: { _controller: my_controller:barAction }
MyController
class MyController extends Controller
{
protected $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
}
Base controller's method get()
is a shortcut for $this->container->get($id);
. $this->container
is set in one of the controller's parent - abstract class ContainerAware
. So,
until object construction is finished, there is no Controller
object that would have get()
method. In general, container
is not available in Controller
's constructor.