{"id":1234,"date":"2022-08-30T15:14:37","date_gmt":"2022-08-30T15:14:37","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/10\/zf2-how-to-get-service-manager-in-mapper-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:14:37","modified_gmt":"2022-08-30T15:14:37","slug":"zf2-how-to-get-service-manager-in-mapper-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/zf2-how-to-get-service-manager-in-mapper-collection-of-common-programming-errors\/","title":{"rendered":"zf2: how to get service manager in mapper-Collection of common programming errors"},"content":{"rendered":"<p>First of all, I think you mean that you want to access the service manager from a mapper class and not a model. I would refrain from doing the latter. Please see my comment to Raj&#8217;s answer for more details.<\/p>\n<p>Secondly, there are many ways to go about this. In this answer, I will give you an example of one approach and merely mention another.<\/p>\n<p>Looking at the service manager&#8217;s documentation (scroll a bit down), it states that a default initializer is added as default. This initializer checks to see if an object that is being retrieved from the service manager implements <code>Zend\\ServiceManager\\ServiceLocatorAwareInterface<\/code>. If it does, the service manager is injected into the object. Thus, this can happen automatically if you simply implement the interface in your mapper classes. You could use an abstract base class to avoid rewriting this for every mapper class. Perhaps something like the below.<\/p>\n<p>Base mapper class:<\/p>\n<pre><code>namespace User\\Mapper;\n\nuse Zend\\ServiceManager\\ServiceLocatorAwareInterface;\nuse Zend\\ServiceManager\\ServiceLocatorInterface;\n\nclass AbstractMapper implements ServiceLocatorAwareInterface {\n    protected $service_manager;\n\n    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)\n    {\n        $this-&gt;service_manager = $serviceLocator;\n    }\n\n    public function getServiceLocator()\n    {\n        return $this-&gt;service_manager;\n    }\n}\n<\/code><\/pre>\n<p>Mapper class:<\/p>\n<pre><code>namespace User\\Mapper;\n\nuse User\\Mapper\\AbstractMapper;\n\nclass UserMapper extends AbstractMapper {\n    public function doSomething() {\n        $sm = $this-&gt;getServiceLocator();\n        $sm-&gt;get('something');\n    }\n}\n<\/code><\/pre>\n<p>Since the service manager is injected when the initializer is run, the mapper should be retrieved from the service manager. If you do not want\/have to inject anything into your mapper class, then an invokable can suffice. They can be added under the <code>invokables<\/code> key, which is nested under the <code>service_manager<\/code> key in <code>module_name\/config\/module.config.php<\/code>. Or, it can be configured in the module class&#8217; <code>getServiceConfig<\/code> method. However, your mapper classes will most likely have some dependencies now or in the future, so you will probably want to use a factory instead. This way, you could for instance have the service manager inject a table gateway into the mapper classes.<\/p>\n<pre><code>\/\/ Remember to include the appropriate namespaces\nreturn array(\n    'factories' =&gt; array(\n        'User\\Mapper\\UserMapper' =&gt; function($service_manager) {\n            $table_gateway = $service_manager-&gt;get('User\\Model\\DbTable\\UserGateway');\n            return new UserMapper($table_gateway);\n        },\n    ),\n);\n<\/code><\/pre>\n<p>The above can be added in a <code>getServiceConfig<\/code> method within the module&#8217;s <code>Module.php<\/code> file &#8211; or add the <code>factories<\/code> key within the <code>service_manager<\/code> key in <code>module_name\/config\/module.config.php<\/code>. You will still have to add a factory that creates the database gateway; the above is just an example.<\/p>\n<p>This is how I would go about it. Of course one could simply have a getter and setter method for the service manager in the mapper class and access these from the controller (the controller has a <code>getServiceLocator<\/code> method) and inject it like that. I would not go with that approach myself, though.<\/p>\n<p id=\"rop\"><small>Originally posted 2013-11-10 00:11:20. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>First of all, I think you mean that you want to access the service manager from a mapper class and not a model. I would refrain from doing the latter. Please see my comment to Raj&#8217;s answer for more details. Secondly, there are many ways to go about this. In this answer, I will give [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1234","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=1234"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1234\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=1234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=1234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=1234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}