Last active
December 3, 2021 09:30
-
-
Save Ocramius/7435899 to your computer and use it in GitHub Desktop.
`Zend\ServiceManager` examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vendor | |
composer.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\AbstractFactoryInterface; | |
use Zend\ServiceManager\ServiceLocatorInterface; | |
use Zend\ServiceManager\ServiceManager; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
// abstract factories provide a way of mapping multiple services in one shot | |
class MyAbstractFactory implements AbstractFactoryInterface | |
{ | |
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) | |
{ | |
return true; // always able to instantiate the service | |
} | |
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) | |
{ | |
$object = new stdClass(); | |
$object->name = $name; | |
$object->requestedName = $requestedName; | |
return $object; | |
} | |
} | |
class MySecondAbstractFactory implements AbstractFactoryInterface | |
{ | |
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) | |
{ | |
return 'tab' === $name; | |
} | |
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) | |
{ | |
return new stdClass(); | |
} | |
} | |
$sm = new ServiceManager(); | |
$sm->addAbstractFactory('MySecondAbstractFactory'); | |
// abstract factories are stacked - careful with that! | |
$sm->addAbstractFactory('MyAbstractFactory', false); | |
$a = $sm->get('foo'); | |
$b = $sm->get('Bar'); | |
$c = $sm->get('BAZ'); | |
$d = $sm->get('tab'); | |
// $d is actually built by MySecondAbstractFactory | |
var_dump($a, $b, $c, $d); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"require": { | |
"zendframework/zend-servicemanager": "2.2.*" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\ServiceManager; | |
use Zend\ServiceManager\Config; | |
die('Not a runnable example'); | |
// this example shows the entire Zend\ServiceManager\Config structure | |
$sm = new ServiceManager(new Config([ | |
'factories' => [ | |
'serviceName' => 'factoryClassOrInstance', | |
], | |
'invokables' => [ | |
'serviceName' => 'className', | |
], | |
'services' => [ | |
'serviceName' => $instance, | |
], | |
'aliases' => [ | |
'alias' => 'serviceName', | |
], | |
'abstract_factories' => [ | |
'stack', | |
'of', | |
'abstractfactory', | |
'classes', | |
'or', | |
'instances', | |
], | |
'delegators' => [ | |
'serviceName' => [ | |
'stack', | |
'of', | |
'delegatorServiceName', | |
'or', | |
'className', | |
'or', | |
'instance' | |
] | |
], | |
'shared' => [ | |
'serviceName' => false, | |
] | |
])); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\DelegatorFactoryInterface; | |
use Zend\ServiceManager\ServiceLocatorInterface; | |
use Zend\ServiceManager\ServiceManager; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
// Delegators are useful when we want to replace a service | |
// but still want to retain the original instance as well | |
// as its instantiation logic. | |
$sm = new ServiceManager(); | |
$sm->setFactory('foo', function () { | |
$service = new \stdClass(); | |
$service->first = 1; | |
$service->second = 2; | |
$service->third = 3; | |
return $service; | |
}); | |
// this delegator replaces the passed in service with an `stdClass` containing | |
// the real service | |
class MyDelegator implements DelegatorFactoryInterface | |
{ | |
public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback) | |
{ | |
$obj = new stdClass(); | |
$obj->service = $callback(); | |
return $obj; | |
} | |
} | |
$sm->addDelegator('foo', 'MyDelegator'); | |
var_dump($sm->get('foo')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\FactoryInterface; | |
use Zend\ServiceManager\ServiceLocatorInterface; | |
use Zend\ServiceManager\ServiceManager; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
$sm = new ServiceManager(); | |
// callable factory | |
$sm->setFactory('foo', function () { return new \stdClass(); }); | |
$a = $sm->get('foo'); | |
$b = $sm->get('foo'); | |
$c = $sm->get('foo'); | |
var_dump($a, $b, $c); | |
// factories can (and should!) be defined as classes | |
class MyFactory implements FactoryInterface | |
{ | |
public function createService(ServiceLocatorInterface $serviceLocator) | |
{ | |
return new stdClass(); | |
} | |
} | |
$sm->setFactory('bar', 'MyFactory'); | |
$d = $sm->get('bar'); | |
$e = $sm->get('bar'); | |
$f = $sm->get('bar'); | |
var_dump($d, $e, $f); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\ServiceManager; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
// initializers are called on every instantiated service, so they | |
// are useful in some cases, but expensive and "magic", since they | |
// may overwrite values set in factories | |
$sm = new ServiceManager(); | |
// note: can also be an InitializerInterface instance | |
// also: initializers are also stacked - careful about their order! | |
$sm->addInitializer(function ($instance) { | |
$instance->initialized = true; | |
}); | |
$sm->setInvokableClass('foo', 'stdClass', false); | |
$a = $sm->get('foo'); | |
$b = $sm->get('foo'); | |
$c = $sm->get('foo'); | |
var_dump($a, $b, $c); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\ServiceManager; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
$sm = new ServiceManager(); | |
// invokables are shared by default | |
$sm->setInvokableClass('foo', 'stdClass'); | |
$a = $sm->get('foo'); | |
$b = $sm->get('foo'); | |
$c = $sm->get('foo'); | |
var_dump($a, $b, $c); | |
// marking the invokable as non-shared (works in general for services) | |
$sm->setInvokableClass('bar', 'stdClass', false); | |
$d = $sm->get('bar'); | |
$e = $sm->get('bar'); | |
$f = $sm->get('bar'); | |
// new instances at every `get`: | |
var_dump($d, $e, $f); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Zend\ServiceManager\AbstractPluginManager; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
// plugin managers are useful to map a set of services sharing a similar | |
// characteristic (in this case the interface). | |
// Zend\Mvc uses 7 or 8 different plugin managers to lazily initialize | |
// forms, form elements, view helpers, validators, controllers, etc... | |
interface Cookie {}; | |
class ChocolateCookie implements Cookie {}; | |
class ButterCookie implements Cookie {}; | |
class Car {}; | |
class CookieFactory extends AbstractPluginManager | |
{ | |
public function validatePlugin($plugin) | |
{ | |
if (! $plugin instanceof Cookie) { | |
throw new \Zend\ServiceManager\Exception\RuntimeException('Not a cookie!'); | |
} | |
} | |
} | |
$sm = new CookieFactory(); | |
$sm->setInvokableClass('chocolate', 'ChocolateCookie'); | |
$sm->setInvokableClass('butter', 'ButterCookie'); | |
$sm->setInvokableClass('not-a-cookie', 'Car'); | |
var_dump($sm->get('chocolate')); | |
var_dump($sm->get('butter')); | |
// this will crash: | |
var_dump($sm->get('not-a-cookie')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment