zf3 getServiceManager in constructor of controller - zend-framework3

How I can call method getServiceManager in constructor of controller?
If I in action method it's ok
public function __construct()
{
$this->logger = $this->getEvent()->getApplication()->getServiceManager()->get("Zend\Log\Logger\Debug");
}
, but in constructor getServiceManager give error:
Call to a member function getServiceManager() on null in C:\htdocs\test-zend2\module\Application\src\Controller\IndexController.php on line 32.

Related

Define a service with lazy loading logger in symfony

How to inject in a Symfony service the Logger component in lazy mode using DI. My intention is to log information in some methods. The logger instance must be created at the first time is used.
Something like this:
namespace App\Services;
use Psr\Log\LoggerInterface;
class XxxService{
private $logger;
public function some_method(){
echo "method without logging"
return $this;
}
private function _log($text){
if(!$this->logger) $this->logger = new LoggerInterface(); //wrong approach creating object from Interface
$this->logger->info($text)
}
public function method_withlog(){
$this->_log("text logged")
return $this;
}
}
(new XxxService()))
->some_method()
->method_withlog() //here is created
->some_method()->method_withlog();

In symfony, how to directly create an object as a service call?

How can I directly create an object instance in a certain way? This object is a task handler, the processor of each task may be different. Is it similar to the method of Yii::createObject(). I don’t want to register handlers in service.yarml, because there may be many handlers.
Here is what I would like to acheive:
$task = new Task;
// $handler = $this->container->get($task->getHandlerName());
$handler = createObject($task->getHandlerName());
$handler->handle($task);
// Handler
class MyHandler {
private $manager;
// autowiring
public function __construct(EntityManagerInterface $manager) {
$this->manager = $manager;
}
public function handle() {
}
}

Error: Call to a member function add() on null

I'm trying to use the embed multiple form in a single form. I have an issue in setting a value for the sub entity. I have included required namespace and methods for this concept. Below is the line of code in controller
$ticket = new EventTicket();
$sale1 = new EventSaleItem();
$sale1->setName('value1');
$ticket->getSales()->add($sale1);
// Ticket entity
public function getSales()
{
return $this->sales;
}
You have to initialize the sales in your Ticket constructor to avoid this error:
// Ticket entity
use Doctrine\Common\Collections\ArrayCollection;
Class Ticket{
public function __construct()
{
$this->sales = new ArrayCollection();
//...
}

Symfony: Why is method $this->get() not available in constructor?

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.
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.
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;
}
}

Calling controller inside a controller

Why it gives the following error when calling controller inside a controller?
Fatal error: Call to a member function get() on a non-object in
/home/web/project/symfony2/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
on line 149
In the controller I called a class that extends Controller:
class DemoController extends Controller
{
public function indexAction()
{
$object = new \Acme\DemoBundle\Service\Object();
$object->method();
}
// ...
}
The class is something like this:
# Acme/DemoBundle/Service/Object.php
class Object extends Controller
{
public function method()
{
$em = $this->getDoctrine()->getEntityManager(); // the problem
// ...
}
}
When I use $this to call service, doctrine, or something else like within a controller, the error occurred. Otherwise, it works.
How can I use, for example, doctrine inside this class?
Try
$object->setContainer($this->container);
before you call method()
Edit:
Basically it's a bad idea to have a service extend Controller but if you really need to do this, try to add this
your.service:
class: Your\Class
arguments: [...]
calls:
- [ setContainer, [#service_container] ]
in your service configuration file (probably service.yml)

Resources