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…)

Advertisements

Using ZF2’s Event Manager Component as Event Driven Programming Example March 27, 2014

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

Zend Framework 2 logoA fundamental principle of Java , .NET platform and other  popular programming languages is based on Event-driven Architecture (EDA). Simply put, the idea is that activities occur in response to events . In other words, activities are attached to events, and when a given event occurs, its attached activity[ies] is[are] executed.This programming paradigm is named  “event-driven programming”  and is nowadays adopted by almost all programming languages (client / server side) . Although event-driven programming was adopted by each programming language for a completely different purpose, the ultimate goal was to write applications that are flexible, scalable and “plug-able” at run-time . Of course , each language has its own implementation, but at the end , all of them were envisioned by the same concepts .

Event-driven programs can be written in any language, although the task is easier in languages that provide high-level abstractions, such as Closures .Back in December 2010 , PHP 5.3 was released . Three of the most notable new features of that release were : support for namespacesLate static binding and Lambda Functions / Closures . At that time , many PHP Frameworks started to flirt with event-driven architecture which leaded to a permanent relation . Laravel-4 , Symfony-2 and Zend Framework-2 have now event driven functionality incorporated into their core . But that’s just history, lets bypass this introductory chatter and go straight to the point .

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/zend-eventmanager": "2.*",

	}

}

 

This article will demonstrate a practical example of using “events” into a standalone code base . For no specific reason , Zend Framework 2’s “Event Manager” component was used to off-load the implementation of an “Observer Design pattern” (we don’t forget the DRY principle) .We could had used Laravel’s , Symfony’s or similar components provided from other component-based PHP Frameworks .

 

Terminology first : The way how events are raised and how listeners are attached on the events is a part of a core in many modern Frameworks. It plays an important role in some enterprise design patterns (MVC, for example) . The basic event terminology includes the following terms:

  • EventManager — is just an object that holds collection of listeners for one or more named events and which trigger events.
  • Event — is a named action .
  • Listener — is a php callback (Closure) that can react to an event
  • Target — is an object that creates events

hooray picturehooray — hooray  , boring introduction is ended . Let’s have fun ……..
A two thousand meter view : Three necessary steps to start using events are :

  • Step1: An EventManager Object (or a derivative) . Our example below will use an abstract “EventProvider” Class which extends ZF’s EventManager .
  • Step2: Registering (attaching) one or more listeners on one or more events .
  • Step3: Calling an event (triggering an event) . All attached listeners will take actions . For illustration and simplicity our examples below use closures as listeners . However, any valid PHP callback can be attached as a listeners : PHP function names, static class methods, object instance methods, functions, or closures.

The following example was copied from ZF’s documentation :

use Zend\EventManager\EventManager;

$events = new EventManager();
$events->attach('do', function ($e) {
    $event = $e->getName();
    $params = $e->getParams();
    printf(
        'Handled event "%s", with parameters %s',
        $event,
        json_encode($params)
    );
});

$params = array('foo' => 'bar', 'baz' => 'bat');
$events->trigger('do', null, $params);

(more…)