jump to navigation

Using ZF2′s ServiceManager Component to Lazy-load Dependencies on Standalone Codebases April 5, 2014

Posted by Tournas Dimitrios in PHP, Zend Framework 2.
Tags: , ,
1 comment so far

Zend Framework 2 logoThis article is intended to familiarize you with various features of  Zend Framework 2’s ServiceManager component (in short, SM). By demonstrating a couple of practical examples, concepts like : IOC , DI and SOLID principles are better digested. So, what is the ServiceManager used for ? In simple words, it’s a registry, or container that “holds” various objects needed by our application, allowing us to easily implement Inversion of Control. The main goal here is to be able to wire up and configure our application from the highest level possible. This results into an testable/maintainable and pluggable application (which I believe, is an objective of every [PHP] developer) .
By default, Zend Framework 2 utilizes Zend\ServiceManager\ServiceManager within its MVC layer (SM “plays” a central role). As such, knowing various features of this component (the SM) will allow us to better understand how  Zend Framework 2 is structured. Although the official documentation has an extensive introduction to SM’s concepts , it might be intimidating for a newcomer . This article will take an alternative approach to demonstrate SM’s basic features , it will detach the component from ZF2’s MVC layer and use it as a supplementary ingredient  into a standalone code-base. Besides all , ZF is composed from loosely coupled components .

Each object registered into SM provides a specific service to our application. A common web-application has services for : mailing , logging , authentication , session , database-connection , temporarily-storage … (the list goes on) . We distinguish these services by the kind of service they provide and how these services are instantiated (while some [objects|services] are autonomous blocks ,other objects have dependencies) . Zend Framework 2’s SM component has “labeled” its registered services (objects) as follows :

  • invokables
  • factories
  • aliases
  • initializers
  • abstract-factories

The official documentation has made a very good job in this regard (describing each service) , replicating its content has totally no meaning (neither could I do a better description) . In contrast , this article will use the first four services from the list ( invokables , factories , aliases and initializers) to build a simple logging application . The last service-type (abstract-factories) is omitted because it is difficult to demonstrate its functionality without breaking the barriers of this article’s simplicity .

Prerequisites : The reader should have a good grasp of OOP concepts . Also knowing to use Composer’s basic functionality is helpful , as it will be used to offload basic tasks like : downloading the required component and using its auto-load functionality .
Composer file used for this article :

{
	"repositories": [
		{
		    "type": "composer",
		    "url": "https://packages.zendframework.com/"
		}
	],
	"require": {
		"zendframework/zendframework": "2.2.*",
		"firephp/firephp-core": "*"
	}

}

Beside the fact that Zend Framework 2’s ServiceManager allows us to programmatically configure the instantiation of  objects (services) and their associated dependencies, these services are only instantiated the moment there is a need for their functionality. The process of instantiating a service/object (and its associated dependencies) at the moment these services are required, is named “Lazy loading” (I know , funny technical jargon). Three examples will clearly describe what I’m talking about :

  1. Why would we instantiate an object (service) if that object is not used by our application ? For instance  : why would we go through the whole process of querying a remote service , while we  have already cached the data from a previous request ?
  2. Why would we go through the whole process of establishing a database connection while our visitor hasn’t used the database in this current visit (for instance , he/she canceled the process of updating a Blog-article).
  3. Why would we go through the whole process of initiating a “Logging” object while this object will not be required on current request . For instance, our application was configured to “Log”  errors , but there hasn’t occurred an error during current session.

All frameworks nowadays ,  have plethora of features (services) . These services might be consumed, or might not be consumed (that  decision will be made by the visitor, most likely, momentarily ) . Lazy-loading has a notable impact into an application’s performance (CPU-cycles , memory consumption).

hooray picture

 

Hooray …. hooray , boring introduction is finished. Let’s begin the show with three practical examples .  (more…)