Zend\ServiceManager?

The Service Locator design pattern is implemented by the Zend\ServiceManager component. The Service Locator is a service/object locator, tasked with retrieving other objects. Following is the Zend\ServiceManager\ServiceLocatorInterface API:

1
2
3
4
5
6
7
namespace Zend\ServiceManager;

interface ServiceLocatorInterface
{
    public function get($name);
    public function has($name);
}
  • has($name), tests whether the ServiceManager has a named service;
  • get($name), retrieves a service by the given name.

A Zend\ServiceManager\ServiceManager is an implementation of the ServiceLocatorInterface. In addition to the above described methods, the ServiceManager provides additional API:

  • Service registration. ServiceManager::setService allows you to register an object as a service:

    1
    2
    3
    4
    5
    $serviceManager->setService('my-foo', new stdClass());
    $serviceManager->setService('my-settings', array('password' => 'super-secret'));
    
    var_dump($serviceManager->get('my-foo')); // an instance of stdClass
    var_dump($serviceManager->get('my-settings')); // array('password' => 'super-secret')
    
  • Lazy-loaded service objects. ServiceManager::setInvokableClass allows you to tell the ServiceManager what class to instantiate when a particular service is requested:

    1
    2
    3
    $serviceManager->setInvokableClass('foo-service-name', 'Fully\Qualified\Classname');
    
    var_dump($serviceManager->get('foo-service-name')); // an instance of Fully\Qualified\Classname
    
  • Service factories. Instead of an actual object instance or a class name, you can tell the ServiceManager to invoke a provided factory in order to get the object instance. Factories may be either a PHP callback, an object implementing Zend\ServiceManager\FactoryInterface, or the name of a class implementing that interface:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    use Zend\ServiceManager\FactoryInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class MyFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $serviceLocator)
        {
            return new \stdClass();
        }
    }
    
    // registering a factory instance
    $serviceManager->setFactory('foo-service-name', new MyFactory());
    
    // registering a factory by factory class name
    $serviceManager->setFactory('bar-service-name', 'MyFactory');
    
    // registering a callback as a factory
    $serviceManager->setFactory('baz-service-name', function () { return new \stdClass(); });
    
    var_dump($serviceManager->get('foo-service-name')); // stdClass(1)
    var_dump($serviceManager->get('bar-service-name')); // stdClass(2)
    var_dump($serviceManager->get('baz-service-name')); // stdClass(3)
    
  • Service aliasing. With ServiceManager::setAlias you can create aliases of any registered service, factory or invokable, or even other aliases:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    $foo      = new \stdClass();
    $foo->bar = 'baz!';
    
    $serviceManager->setService('my-foo', $foo);
    $serviceManager->setAlias('my-bar', 'my-foo');
    $serviceManager->setAlias('my-baz', 'my-bar');
    
    var_dump($serviceManager->get('my-foo')->bar); // baz!
    var_dump($serviceManager->get('my-bar')->bar); // baz!
    var_dump($serviceManager->get('my-baz')->bar); // baz!
    
  • Abstract factories. An abstract factory can be considered as a “fallback” factory. If the service manager was not able to find a service for the requested name, it will check the registered abstract factories:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\ServiceManager\AbstractFactoryInterface;
    
    class MyAbstractFactory implements AbstractFactoryInterface
    {
        public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
        {
            // this abstract factory only knows about 'foo' and 'bar'
            return $requestedName === 'foo' || $requestedName === 'bar';
        }
    
        public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
        {
            $service = new \stdClass();
    
            $service->name = $requestedName;
    
            return $service;
        }
    }
    
    $serviceManager->addAbstractFactory('MyAbstractFactory');
    
    var_dump($serviceManager->get('foo')->name); // foo
    var_dump($serviceManager->get('bar')->name); // bar
    var_dump($serviceManager->get('baz')->name); // exception! Zend\ServiceManager\Exception\ServiceNotFoundException
    
  • Initializers. You may want certain injection points to be always called. As an example, any object you load via the service manager that implements Zend\EventManager\EventManagerAwareInterface should likely receive an EventManager instance. Initializers are PHP callbacks or classes implementing Zend\ServiceManager\InitializerInterface. They receive the new instance, and can then manipulate it:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\ServiceManager\InitializerInterface;
    
    class MyInitializer implements InitializerInterface
    {
        public function initialize($instance, ServiceLocatorInterface $serviceLocator)
        {
            if ($instance instanceof \stdClass) {
                $instance->initialized = 'initialized!';
            }
        }
    }
    
    $serviceManager->setInvokableClass('my-service', 'stdClass');
    
    var_dump($serviceManager->get('my-service')->initialized); // initialized!
    

In addition to the above, the ServiceManager also provides optional ties to Zend\Di, allowing Di to act as an initializer or an abstract factory for the service manager.

Previous topic

Zend\Server\Reflection

Next topic

Zend\ServiceManager Quick Start

This Page

Note: You need to stay logged into your GitHub account to contribute to the documentation.

Edit this document

Edit this document

The source code of this file is hosted on GitHub. Everyone can update and fix errors in this document with few clicks - no downloads needed.

  1. Login with your GitHub account.
  2. Go to Zend\ServiceManager on GitHub.
  3. Edit file contents using GitHub's text editor in your web browser
  4. Fill in the Commit message text box at the end of the page telling why you did the changes. Press Propose file change button next to it when done.
  5. On Send a pull request page you don't need to fill in text anymore. Just press Send pull request button.
  6. Your changes are now queued for review under project's Pull requests tab on GitHub.