Search code examples
zend-framework2

ZF2 - How to inject a service to a view?


I have a service class MyService that I use on the controllers by passing it as a parameter in the controller constructor. Needless to say, I use a factory to instantiate the controllers, and use the factory's service locator to retrieve MyService and then pass it to the instantiated controller.

// factory
$sl = $sl->getServiceLocator();
$ms = $sl->get(MyService::class);

return new MyController($sm);

Now, I need that service in the view. I tried creating a view helper that would take MyService as a dependency, (similar to the controller) like this:

// view helper factory
$ms = $sl->get(MyService::class);

return new MyServiceViewHelper($ms);

However, it won't correctly instantiate MyService. It crashes saying:

Catchable fatal error: Argument 1 passed to MyService::__construct() must be an instance of MyRepository, none given, called in /my-path/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php

MyService takes about 3 repositories as dependencies, that are provided naturally by the MyServiceFactory. However, for some reason, the view helper isn't properly calling the factory or something like that, resulting in an incorrect instantiation.

So my next thought is: maybe this is not how you inject services to the view. So now I ask:

How do I inject services to the views themselves?

Edit: please don't say "pass it from the controller".


Solution

  • The viewhelpers are retrieved from a seperate pluginmanager HelperPluginManager, the same applies for the controllers which are managed by the ControllerManager. To retrieve services from the "root" serviceManager you have to call getServiceLocator() in your factory as you did in the controller factory.

    So your code should be:

    // view helper factory
    $sl = $sl->getServiceLocator(); //This line will do the trick
    $ms = $sl->get(MyService::class);
    
    return new MyServiceViewHelper($ms);