Pragmatism in the real world

Zend\ServiceManager configuration keys

Zend\ServiceManager is usually configured in two places: an array in a config file or a method within your Module class. In either case, you provide a nested array of configuration information.

For example, in a config file:

return array(
    'service_manager' => array(
        'invokables' => array(
            'session' => 'ZendSessionStorageSessionStorage',
        ),
        'factories' => array(
            'db' => 'ZendDbAdapterAdapterServiceFactory',
        ),
    )
);

Within the service_manager array, there are a set of nested arrays which are generally used to configure how you want a given class to be instantiated. the names of these sub-arrays are hardcoded, so you just need to learn their names and the difference between them:

invokables

A string which is the name of a class to be instantiated. The ServiceManager will instantiate the class for you when needed. For example:

'invokables' => array(
    'zfcuser_user' => 'UserServiceUser'
),
services

An instance of a class. This is used to register already instantiated objects with the ServiceManager. For example:

'services' => array(
    'rob' => $rob,  // $rob is already instantiated 
),
factories

A callback that will return an instantiated class. This is for cases where you need to configure the instance of the object. For example:

'factories' => array(
    'MyModuleMapperComment' =>  function($sm) {
        $mapper = new MyModuleMapperComment();
        $db = $sm->get('ZendDbAdapterAdapter');
        $mapper->setDbAdapter($db);
        return $mapper;
    },
),
aliases

Another name for a class. Generally, you see this used within a module so that the module uses it’s own alias name and then the user of the module can configure exactly which class that alias name is to be.
For example:

'aliases' => array(
    'mymodule_zend_db_adapter' => 'ZendDbAdapterAdapter',
),
initializers

A callback that is executed every time the ServiceManager creates a new instance of a class. These are usually used to inject an object into the new class instance if that class implements a particular interface.
For example:

'initializers' => array(
    function ($instance, $sm) {
        if ($instance instanceof AuthorizeAwareInterface) {
            $instance->setAuthorizeService($sm->get('auth_service'));
        }
    }
)

In this case, the initialiser checks if $instance implements AuthorizeAwareInterface and if it injects the Authorize service into the instance ready for use. Another really common use-case is injecting a database adapter and Zend Framework supplies ZendDbAdapterAdapterAwareInterface for this case.

There is also the abstract_factories key, but this is rarely used in most apps.

abstract_factories

A factory instance that can create multiple services based on the name supplied to the factory. This is used to enable ServiceManager to fallback to another Service Locator system if it can cannot locate the required class from within its own configuration. As an example, you could write an abstract factory that proxies to Symfony’s DependencyInjection component. Items within this sub-key can be either a classname string or an instance of the factory itself For example:

array('abstract_factories' => array( 
    new DiStrictAbstractServiceFactory(),
);

All abstract factories must implement ZendServiceManagerAbstractFactoryInterface.

Controllers, View helpers & Controller plugins

Note that the MVC system instantiates controllers, view helpers, form elements, input filters, controller plugins and others using specialised versions of ServiceManager. This means that the same keys that you use for service manager configuration are used for setting up view helpers and controller plugins, etc. – you just use a different top level configuration key and method name the in Module class:

Manager Key name in configuration array Method name in Module.php
ServiceManager service_manager getServiceConfig()
ViewHelperManager view_helpers getViewHelperConfig()
ControllerPluginManager controller_plugins getControllerPluginConfig()
ControllerManager controllers getControllerConfig()
ValidatorManager validators getValidatorConfig()
FilterManager filters getFilterConfig()
FormElementManager form_elements getFormElementConfig()
RoutePluginManager route_manager getRouteConfig()
SerializerAdapterManager serializers getSerializerConfig()
HydratorManager hydrators getHydratorConfig()
InputFilterManager input_filters getInputFilterConfig()

This is reuse of knowledge at its best!

8 thoughts on “Zend\ServiceManager configuration keys

  1. Thanks! That was exactly what I was looking for three days ago!

    That will save me a lot of time!

  2. The following will be added in ZF 2.1:

    Manager : FormElementManager
    Key name in configuration array : form_elements
    Method name in Module.php : getFormElementConfig

  3. so, the [services] have to be used with either [factories] or [invokables] ?

    if [services] register already instantiated objects, those objects can be already instantiated only by either a [factory] of an [invokable] at that configuration level, right?

    thanks for the tutorial.

  4. Doesn't getControllerConfig() use an instance of ControllerManager? I know that is what I've been using.

  5. Michael,

    You're right.

    The key in the SM is ControllerLoader, but it's an instance of ControllerManager and it's created in the ControllerLoaderFactory class.

    Regards,

    Rob…

Comments are closed.