Your SlideShare is downloading. ×
0
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Zf2 phpquebec
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Zf2 phpquebec

2,760

Published on

ZF2 Modules and Service locators....

ZF2 Modules and Service locators....

Published in: Technology, Art & Photos
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,760
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
62
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. ZF2 Modules and Services (And DI)Maurice KherlakianZend Technologies © All rights reserved. Zend Technologies, Inc.
  • 2. Who am I? • Zend Professional Services consultant • Worked with PHP for about 10 years • Based in Montreal Linkedin: http://ca.linkedin.com/in/mkherlakian Twitter: http://twitter.com/mkherlakian Email: maurice.k@zend.com2 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 3. ZF2 Modules – What are they? • Discrete blocks of code • Allow for code re-use (not only within ZF2 but with other frameworks – Sf2 anyone?) • Physically a namespaced directory • If written well, distributable and re-usable • Examples:  User module (authentication – login/logout…)  ACL module  Blog module3 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 4. Why are they better than ZF1’s modules • ZF1 modules had serious problems • Tightly coupled with MVC • Could not be easily reused • Bootstrapping expensive • Not self-contained • No dependency management ZF2 addresses all of these problems4 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 5. Requirements for a module – Module class • A namespaced class called Module <?php namespace Mymod; class Module {} • That’s it!5 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 6. Requirements for a module – Directory structure • There is, of course, a recommended directory structure6 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 7. Requirements for a module - Registration • In order for the application (Zend/Application) to run your module, it has to be registered <?php //application.config.php return array( modules => array( //Which modules are we loading? Application, Mymod, ), module_listener_options => array( config_glob_paths => array( config/autoload/{,*.}{global,local}.php, ), config_cache_enabled => false, cache_dir => data/cache, module_paths => array( //What paths are we loading modules from? ./module, //We will look for a Module.php file in subdirs ./vendor, //one level down from this dir *by default* ), ), service_manager => array( //More on that later use_defaults => true, factories => array( ), ), );7 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 8. Optional for a module – getConfig() • Called automatically to get the module’s configuration and aggregate it with the other modules • Best is to include a config file that returns a php array (best practice in ZF2 in general) <?php namespace Mymod; use ZendModuleManagerModuleManager, ZendMvcMvcEvent; class Module { public function getConfig() { return include(__DIR__./config/module.config.php); } }8 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 9. Optional for a module – init() • A module can have an init() method that fires upon initialization • The ModuleManager is passed to the init function as an argument <?php namespace Mymod; use ZendModuleManagerModuleManager, ZendMvcMvcEvent; class Module { public function init(ModuleManager $e) { $e->events()->attach( loadModules.post, function($e) { echo postLoad from MyMod; }, 100); $e->events()->getSharedManager()->attach( __NAMESPACE__, dispatch, function($e) { echo "Only if dispatched to Mymod"; }, 100); } }9 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 10. Optional for a module – onBootstrap() • And if init() is too early, ModuleManager automatically registers the onBootstrap method if found in the module • An MvcEvent is passed as the argument <?php namespace Mymod; use ZendModuleManagerModuleManager, ZendMvcMvcEvent; class Module { public function onBootstrap(MvcEvent $e) { $request = $e->getRequest(); } }10 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 11. Optional for a module – Dep solving • Thru getProvides() and getDependencies() • Off by default, can be turned on <?php namespace Blog; class Module { public function getProvides() { return array( name => Blog, version => 0.1.0, ); } public function getDependencies() { return array( php => array( required => true, version => >=5.3.1, ), ext/mongo => array( required => true, version => >=1.2.0, ), ); } }11 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 12. ModuleManager • It’s automatically instantiated in your ZendApplication • It fulfills 3 functions:  Aggregates enabled modules (allows you to iterate over them)  Aggregates the configuration from each module  Triggers the module initialization • There are many events for which the ModuleManager is passed as an argument • This allows you to provide listeners at practically any point in the code to get access to the manager12 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 13. An MVC module • In most cases that’s what you will want <?php //module.config.php return array( router => array( routes => array( Mymod => array( type => ZendMvcRouterHttpLiteral, options => array( route => /mymod, defaults => array( controller => mymod, action => index, ), ), ), ), ), controller => array( classes => array( mymod => MymodControllerIndexController, ), ), view_manager => array( template_path_stack => array( __DIR__ . /../view, ), ), );13 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 14. The missing link - bootstrapping – index.php <?php // /public/index.php require_once Loader/StandardAutoloader.php; use ZendLoaderStandardAutoloader, ZendServiceManagerServiceManager, ZendMvcServiceServiceManagerConfiguration; $loader = new StandardAutoloader(); $loader->registerNamespace(Application, module/Application/src/Application); $loader->registerNamespace(Mymod, module/Mymod/src/Application); spl_autoload_register(array($loader, autoload)); // Get application stack configuration chdir(dirname(__DIR__)); $configuration = include config/application.config.php; // Setup service manager $serviceManager = new ServiceManager(new ServiceManagerConfiguration($configuration[service_manager])); $serviceManager->setService(ApplicationConfiguration, $configuration); $serviceManager->get(ModuleManager)->loadModules(); // Run application $serviceManager->get(Application)->bootstrap()->run()->send();14 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 15. The missing link - bootstrapping – index.php • Autoloading – it is the responsibility of index.php to set up autoloading • This is because modules have to be portable between different frameworks (reusability) • Any PSR-0 autoloader should work, it does not have to be ZF2’s autoloader  For example Rob Allen’s Skeleton module uses Composer’s autoloader • The next lines are the ServiceManager’s setup (more on it later)15 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 16. Modules distribution • Any source you can think of  Pyrus  Git  Http  Tar & send  Composer • There is already a ZF2 modules site http://modules.zendframework.com/ (We need help! Want to contribute?)16 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 17. Modules packaging • Tar/Zip • Phar (being careful that writes occur in location external to the archive)17 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 18. Location, location, location DI - short summary • Since the presentation was originally about ZendDi it’s only fair that we talk about it! • DI is the practice of reducing coupling between classes by injecting dependent classes in the subject instead of instantiating them <?php //No DI class DbAdapter { public function __construct($host, $user, $pass, $db) { //... } } class Author { protected $_db; public function __construct($host, $user, $pass, $db) { $this->_db = new DbAdapter($host, $user, $pass, $db); } }18 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 19. Location, location, location DI - short summary <?php //DI class DbAdapter { public function __construct($host, $user, $pass, $db) { //... } } class Author { protected $_db; public function __construct($db) { $this->_db = $db; } } $db = new DbAdapter(); $author = new Author($db); • That’s all it is – Really! Makes it easy to substitute the DB class for mocking, or to change it all together for instance, and promotes decoupling and reusability. The D in SOLID.19 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 20. Location, location, location DI - short summary • Consider the case that an Author needs a DbGateway, which needs a DbAdapter, and a logging and caching class <?php $db = new DbAdapter(); $gateway = new DbGateway($db); $cache = new Cache(); $log = new Log(); $author = new Author($db, $gateway, $cache, $log); $authors = $author->fetchAll(); • 5 lines of code for initialization, but only one line for what we really need to do. Lots of boilerplate code • Enter Dependency Injection Containers, or DiC – ZendDi is one of them, so is the Symfony DiC, and a number of others20 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 21. Location, location, location DiC – ZendDiDi() <?php $config = array( instance => array( Author => array( parameters => array( gateway => DbGateway, cache => Cache, log => Log ) ), DbGateway => array( parameters => array( db => DbAdapter, ) ), DbAdapter => array( parameters => array( host => somehost, user => someuser, pass => somepass, db => ‘somedb ) ), Cache => array( ), Log => array( ) ) ); $di = new ZendDiDi(); $di->configure(new ZendDiConfiguration($config)); $author = $di->get(Author);21 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 22. Location, location, location DiC – ZendDiDi() • The last line on the previous slide: $author = $di->get(Author); Returns a fully configured Author object, following the definition we provided • DiC does instantiation and auto-wiring • ZendDi, although difficult to show here, is a complex solution for complex problems – it can easily be abused • For simpler problems, and more in line with the PHP philosophy, ServiceManager replaced it22 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 23. Location, location, location Location v/s Injection • Service manager is a ServiceLocator !== DiC • BUT DiC === Service Locator • One main difference is that the subject requiring the dependencies is:  Not aware of the DiC when using DI (the dependency is injected)  Is aware of the locator in the case of SL, and asks the locator to obtain the dependency • ServiceManager is a service locator Think back to index.php: $serviceManager->get(ModuleManager)->loadModules(); • Martin Fowler is the subject matter expert on this: http://martinfowler.com/articles/injection.html23 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 24. Location, location, location ZendServiceManagerServiceManager() • Service manager uses factories to generate its services • Factory can be a class implementing ZendServiceManagerFactoryInterface or a php closure24 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 25. Location, location, location ZendServiceManagerServiceManager() <?php class ServiceConfiguration extends Configuration { public function configureServiceManager(ServiceManager $serviceManager) { $serviceManager->setFactory(author, function(ServiceManager $sm) { $dbGateway = $sm->get(db_gateway); $cache = $sm->get(cache); $log = $sm->get(log); return new Author($dbGateway, $cache, $log); } ); $serviceManager->setShared(author, false); $serviceManager->setFactory(db_gateway, function(ServiceManager $sm){ $dbAdapter = $sm->get(db_adapter); return new DbGateway($dbAdapter); } ); $serviceManager->setFactory(db_adapter, function(ServiceManager $sm) { //Using hard-coded values for the example, but normally you would either create a factory //and inject the values from a config file //or get the configuration from the ServiceManager and read the valuees in return new DbAdapter(somehost, someuser, somepass, somedb); } ); $serviceManager->setFactory(cache, function(ServiceManager $sm) { return new Cache(); } ); $serviceManager->setFactory(log, function(ServiceManager $sm) { return new Log(); } ); } } $config = new ServiceConfiguration(); $sm = new ServiceManager(); $config->configureServiceManager($sm); $author = $sm->get(author);25 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 26. Location, location, location ZendServiceManagerServiceManager() • The example above purposely uses closures to illustrate that a full-fledged factory is not needed • But in a lot of cases, implementing a factory makes sense - rewriting DbAdapter from the above example as a factory: <?php use ZendServiceManagerFactoryInterface; //The factory class class AuthorFactory implements FactoryInterface { public function createService(ZendServiceManagerServiceLocatorInterface $sl) { $dbGateway = $sl->get(db_gateway); $cache = $sl->get(cache); $log = $sl->get(log); return new Author($dbGateway, $cache, $log); } } //And the configuration class class ServiceConfiguration extends Configuration { public function configureServiceManager(ServiceManager $serviceManager) { //... $serviceManager->setFactory(author, AuthorFactory); //... } }26 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 27. Location, location, location ZendServiceManagerServiceManager() • The example above purposely uses closures to illustrate that a full-fledged factory is not needed • But in a lot of cases, implementing a factory makes sense - rewriting DbAdapter form the above example as a factory: <?php use ZendServiceManagerFactoryInterface; //The factory class class AuthorFactory implements FactoryInterface { public function createService(ZendServiceManagerServiceLocatorInterface $sl) { $dbGateway = $sl->get(db_gateway); $cache = $sl->get(cache); $log = $sl->get(log); return new Author($dbGateway, $cache, $log); } } //And the configuration class class ServiceConfiguration extends Configuration { public function configureServiceManager(ServiceManager $serviceManager) { //... $serviceManager->setFactory(author, AuthorFactory); //... } }27 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 28. Location, location, location Setting and retrieving the locator • In most MVC components (e.g.Controllers) the ServiceManager component is composed automatically by the MVC stack • The interface ZendServiceManagerServiceLocatorAwareInterface can be implemented to ensure that a service locator is composed in the subject class • Two methods, SetServiceLocator(ServiceLocatorInterface $locator) and getServiceLocator() must be implemented • Notice that the Component is ServiceManager(), but the interface is ServiceLocatorInterface. This is to allow you to provide an alternative implementation of service locator.28 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 29. Location, location, location Setting and retrieving the locator • Controllers implement ServiceLocatorAwareInterface therefore <?php namespace MymodController; use ZendMvcControllerActionController, ZendViewModelViewModel; class IndexController extends ActionController { public function indexAction() { $sl = $this->getServiceLocator(); $sl->get(author); return new ViewModel(); } }29 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 30. Locating the injector or injecting the locator? • Although ServiceManager is now the goto dependency management component in ZF2, Di actually still exists as a fallback (by default) • One can specify a collection AbstractFactories to ServiceManager on which it will fall back if it does not find the target class • Therefore, ZendServiceManagerDiDiAbstractFactory is an abstract factory to which the name of the object is passed if it is not found by ServiceManager (the order can be changed) • You can also, of course, provide your own service factory (Proxy class to other frameworks maybe?)30 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 31. Some references • ZF2 module site: http://modules.zendframework.com/ • Rob Allen’s Skeleton: https://github.com/zendframework/ZendSkeletonApplication • Matthew’s discussion on Modules: http://mwop.net/blog/267-Getting- started-writing-ZF2-modules.html • Ralph on the decisions that drove to ServiceManager: http://zend- framework-community.634137.n4.nabble.com/Services-Instances- Dependencies-in-ZF2-td4584632.html • SOLID OO design: http://en.wikipedia.org/wiki/SOLID_(object- oriented_design)31 Zend Professional Services © All rights reserved. Zend Technologies, Inc.
  • 32. • Download ZF2 and happy coding! http://zendframework.com/zf2 Thank You! http://twitter.com/mkherlakian32 Zend Professional Services © All rights reserved. Zend Technologies, Inc.

×