jump to navigation

Getting Started with Aspect Oriented Programming (AOP) in PHP July 29, 2014

Posted by tournasdimitrios1 in PHP.
Tags: ,
add a comment

Smiley Face

The benefits of Object Oriented Programming (OOP) is that it lets us encapsulate – abstract data and functionality away (which is the key for building large systems). We could achieve the same results with other paradigms, but it seems that OOP is especially helpful in this regard. Aspect Oriented Programming (AOP) is a follow-on development to OOP, developed with the intention of solving some of the practical limitations of OOP. The majority of applications a developer writes will contain common functionality that will be shared across the codebase (mailing, logging, caching, debugging, user-notification, security –ACL–, opening a database connection, etc….. ) . Such functionality is generally described as “cross-cutting concerns” because it’s not specifically relevant to any one piece of code where it might be embedded[used]. An example will better illustrate this subject (the following code is meant for illustrative purposes only; any design issues are beside the point) :

namespace MyNamespace\Controllers;

use MyNamespace\Services\Logger;
use MyNamespace\Services\Mailer;
use MyNamespace\Services\Security;
use MyNamespace\Services\AclException;
use MyNamespace\Models\User;

class UserController
{
     /*
     ..................
     Code truncated
     ..................
     */

    /**
    *
    * @param String $username Name of the new User
    */
    public function createNewUser($username)
    {
        $dateTime = date('l jS \of F Y h:i:s A');
        if (!$this->security->isGranted('Security::ROLE_ADMIN'))
        {
            throw new AclException('Only root can assign new users');
        }

        try {
            $user = new User($username);
            $this->entityManager->persist($user);
            $this->entityManager->flush();
        } catch (Exception $e) {
            $this->logger->error('User create error'. $e->getMessage());
            $this->mailer->send('User create error at : '. $dateTime);
        }

            $this->logger->info("User {$username} created at : " . $dateTime);
            $this->mailer->send("User {$username} created at : " . $dateTime);
    }
}

It is evident from the above code that the main role of the UserManager object is to manage users, but beyond this, UserManager has to borrow services from other objects in order to fulfill its operations. Most likely the same motif can be spotted across many places of our application (ie Logging, Mailing and Acl functionality will be used  by many objects).  The aforementioned motif is considered bad practice because it violates fundamental design principles and will lead to a system that isn’t easily maintainable-extendable over time. Let us identify a few of those violations :

  • SoC (Separation of Concerns) : Our UserManager object is tightly coupled to other objects. Distributing / Reusing the UserManager class into other projects has a dependency which must be taken into account.
  • SOLID : The above motif clearly violates the “O” of SOLID (ie the Open/Close principle). For instance, if for some reason one of those service-objects on which UserManager depends, change its functionality, this will affect UserManager (but also all objects that might use those service-objects). Having the task to update the relevant code throughout the entire system is not pleasant at all :)

Cross-cutting concerns  tends to increase the complexity of an application. AOP is a way of modularizing cross-cutting concerns much like object-oriented programming is a way of modularizing common concerns.

(more…)

Five Regular-Expression Concepts a PHP Developer Should Know July 14, 2014

Posted by tournasdimitrios1 in PHP.
Tags: ,
add a comment

Regular expressionsA Regular Expression, also called regex or regexp, is the term used to describe a codified method of searching into a string (or text) for a matched pattern. It was invented by an American mathematician, Stephen Cole Kleene (January 5, 1909 – January 25, 1994). Regex are used for advanced context sensitive searches and text modifications. Although regex are quite wide spread in the Unix world there is no such thing as ‘the standard regular expression language’. It is more like several different dialects. PHP supports two different types of regular expressions: POSIX-extended and Perl-Compatible Regular Expressions (PCRE). While the former is depreciated as of PHP version 5.3 and attempting to use any of its functions will result in the generation of a notice of level  E_DEPRECATED, it is highly encouraged to use the later (PCRE functions), which have native support for utf-8 character set encoding, are more powerful and faster than the POSIX ones.

Excerpt taken from a StackOverflow.com discussion : POSIX (Portable Operating System Interface for Unix) is simply a set of standards that define how to develop programs for UNIX (and its variants). Being POSIX-compliant for an OS means that it supports those standards (e.g., APIs), and thus can either natively run UNIX programs, or at least porting an application from UNIX to the target OS is easy/easier than if it did not support POSIX. Of course, the level of compliance is not necessarily 100% and can vary (e.g., not all features are supported or may be implemented differently).

For who is this article ? : Certainly not for a beginner in the world of “manipulating text programmatically“, neither for those that don’t like to experiment. The reader should have basic knowledge of regex syntax (he/she should be fluent with reading/writing regex patterns, so to speak). We will “talk” about : greediness , internal option settings , lookbehinds , lookaheads, non-capturing sequences and backreferences . Each of those concepts will be explained in brief and accompanied by a practical example.  This article aims to trigger your interest for writing more advanced regex patterns.

For those that need a refresh, at the end of this article (paragraph: “A quick overview of all PCRE functions” ) are practical examples for all PCRE functions. Also tables with metacharacters and pattern-modifiers are showing the most used “tools” (learn these tools by heart if you plan to master PCRE) .Of course, the official documentation is “the way to go”, for an in-depth review of the subject .

Whatever is done with regular expressions can also be achieved with native PHP functions (after all, PHP has close to one hundred functions for text manipulation), with one crucial difference though, regular expressions are doing it in a more efficient way. Not in the context of operating system performance but on the level of writing code. The following example will illustrate what I’m talking about :

/*  */

$contents = array(
    ' ALPHA ΒΑΝΚ ' => ' 0,6320 -0,0530 -7,74% 0,6260 0,6910 46.264.300 30.254.097 -',
    //    ......  truncated  .............  ///
    );

// Using PHP's string manipulation functions
foreach ($contents as $bank_name => $stock_values) {
    $stock_values =  str_replace('%', '', $stock_values);
    //first strip '-' and then strip whitespaces from beginning and end of string
    $cleaned_stock_values = trim(rtrim($stock_values, '-'));
    // the text is sliced and stored into an array
    $values = explode(' ', $cleaned_stock_values );
    $final_contents[$bank_name] =  $values;

}

// Using PCRE functions
foreach ($contents as $bank_name => $stock_values) {
$final_contents[$bank_name] = preg_split('/(-$)|[\s]|[%]/', $stock_values, null, PREG_SPLIT_NO_EMPTY);
}

var_dump($final_contents); 

/*
array (size=1)
  ' ALPHA ΒΑΝΚ ' =>
    array (size=7)
      0 => string '0,6320' (length=6)
      1 => string '-0,0530' (length=7)
      2 => string '-7,74' (length=5)
      3 => string '0,6260' (length=6)
      4 => string '0,6910' (length=6)
      5 => string '46.264.300' (length=10)
      6 => string '30.254.097' (length=10)
*/

/* */

Both approaches in the above code-snippet achieve the same goal, it’s evident that the regular expression solution is more compact (more readable I would say). For the curious spirits out there, the above example is an associative array whose values are strings of stock-market values which have to be sliced into separate entities. Firstly, each string has to be cleaned from unwanted characters (ie : %, – and white-spaces) and then the same string has to be transformed into an array. The outcome of this transformation can be used by Google Charts  and other custom code to extract statistical conclusions in order to create attractive and interactive charts. (more…)

An Overview of Exceptions in PHP July 5, 2014

Posted by tournasdimitrios1 in PHP.
add a comment

php exception graphAn Exception, as the name implies, is any condition experienced by a program that is unexpected or not handled within the normal scope of the code. Exception handling is prevalent among many popular languages ( Java , C++ , C# , Python to name a few) , it was added to PHP with the version 5 release.  When an Exception occurs, PHP’s default behavior is to :

  1. abruptly stop the flow of the program (code following the exception-event will not be executed),
  2. instantiate an object of type “Exception”  and passing valuable information into the object regarding the origin of the error (file , line , error-code, error-message).
  3. display a “Fatal error” message.

We can overwrite this default behavior though, by catching the Exception object, interfering with a custom — predefined — task (ie Logging the event , displaying a user friendly message) and continuing the program flow as nothing has happened. Actually there are two methodologies to catch exceptions (we’ll get into more details later on)

    A few keynotes :

  • Beside the fact that a user facing a “Fatal error” cannot perceive it as a pleasant experience, it might be a serious security risk (revealing sensitive information).
  •  A favorite expression used by developers is : “An Exception is thrown“.
  • Not only PHP’s interpreter can “throw” exceptions, also developers can “throw” exception-events programmatically by using PHP’s “throw” construct .
  • PHP has a long list of built-in exception classes .
  • An exception object can be catched with the “try/catch” construct . Sometimes it is helpful to catch an exception, look at some of its properties, and then re-throw it again. This is often useful to check an error code and decide whether it should be fatal.
    .

Before we dig into practical examples, let’s first present a few characteristics of PHP’s exception mechanism. (more…)

A Sample MVC App Build on Top of Symfony2 and Laravel4 Components (Part-2 Introspection of the Skeleton) June 22, 2014

Posted by tournasdimitrios1 in PHP, sample-MVC.
Tags:
add a comment

Word Cloud SymfonyWelcome back to the second part of the article series “A Sample MVC App Build on Top of Symfony2 and Laravel4 Components”. Every project start with a skeleton, it’s the application’s folder and file structure (a blueprint so to speak). Unfortunately, there are no standards in this regard. While some frameworks (Symfony , Zend-Framework, Laravel) utilizes a skeleton according their own philosophy other frameworks (in particular micro-frameworks) are giving the developer the freedom to structure a skeleton according their own needs. The key point here is that the structure of the skeleton must be planned in such a way that any developer that might get involved into the project will get familiar instantly.

A long time ago :), before PHP released its 5.3 version (at december 2010) we were forced to follow a particular folder structure. Certainly the following motif is familiar to you : class Zend_Application_Module_Autoloader extends Zend_Loader_Autoloader_Resource We had to follow a corresponding folder structure so that the autoloader could do its job, at some extent the same motif is also followed today but we are not forced to do so. PHP Namespaces, which were initially applied as a solution for bypassing naming conflicts between different libraries that could exist in the same project, had also impact how a skeleton could be structured. Due to Composer (a PHP dependency manager), we can now customize its autoloader in a much more flexible way.

The following picture shows the skeleton used by this app : skeleton_of_sampleMVC   A quick overview of each folder :

(more…)

A Sample MVC App Build on Top of Symfony2 and Laravel4 Components (Part-1 Introduction) June 20, 2014

Posted by tournasdimitrios1 in sample-MVC.
Tags:
add a comment

Word Cloud SymfonyThe Model-View-Controller pattern (MVC) is a methodology for separating the concerns of an application’s domain, presentation, and user input into separate (specialized) components. The days where HTML code was intermixed with server-side code to achieve dynamic web-applications are just ancient history (in terms of Internet technology). PHP itself works like a template engine. However, when used irresponsibly, it leads to very ugly and un-maintainable code (not to mention the environment for teamwork). Within the context of web- development environments, MVC is the de facto architectural design pattern, not the only though .
Many PHP frameworks nowadays provide an “out of the box  MVC skeleton” as starting point, a developer has to make a careful plan before he/she decide which framework to choose for the intended project .

This article will present a fully functional MVC application build from components taken from two well known PHP frameworks (ie Symfony2 and Laravel4). The final result is a simple “User list” where users can be registered / updated and deleted from the database (basic CRUD operations) . Not a very useful practical example, one might say. Yes indeed, this simple example might not have a practical implementation. But it’s the best way (IMO) to demonstrate the core concepts of a well structured web application. All frameworks are doing the exact same things to achieve similar functionality, in a more efficient way of course. A lot of Bootstrapping is done behind the scenes until a framework’ skeleton application is ready to respond on requests made by a browser. Just for indicative purposes, Symfony2 / Zend Framework2 are instantiating more than 200 Classes at bootstrap. Many more classes are lazy loaded “just the time” their functionality is required  by using Dependency Injection. Even more, all instantiated Classes are kept as services in a container (a bucket so to speak) for later use (might the application demand their services). The practical example of this article intentionally refrained to use a Dependency Injection Container (DI). Firstly, for simple web applications (as this one) there is no  benefit to make use of it. Secondly, the reader will get a better overview how the puzzle is structured, as everything is on front and nothing is passed over to background functionality (which is the case if we had to use a DI container). An obvious question that might arise is if this code could be used on production. Although my answer is definitely Yes, I will conclude with :  “just because we can doesn’t mean we should“. There are so many frameworks to choose from, this fact makes this code-base not the best choice for a production application that might be extended with extra functionality in the future .
This Blog has already started to publish an article series about Silex. That framework (Silex) can be used as a foundation for all kind of web applications (from prototyping and small web apps up to high demanding web services and API’s) . Of course there are so many alternate solutions out there which could be an excellent choice for our next web application.

(more…)

Including Angular Scripts From the Google CDN May 31, 2014

Posted by tournasdimitrios1 in AngularJs.
Tags:
add a comment

angular-logoThe number one reason for using a CDN is to improve our website visitor’s experience in terms of speed. As we know, site speed is a ranking factor in Google’s algorithm. The quickest way to get started is to point a <script>  tag to a Google CDN URL. There are two types of angular script URLs we can point to, one for development (angular.js –80Kb size–) and one for production (angular.min.js –30Kb size–) . While the development version (non-minified version) is suitable for web development and displays detailed error reporting messages, the production version (minified version) is the suggested.
A quick reference for the most used Angular scripts provided by Google’s CDN :

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js"></script><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-cookies.min.js"></script><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-resource.min.js"></script><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.min.js"></script><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-sanitize.min.js"></script><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-touch.min.js"></script>

Those developers  who want to work with angular offline, or those who want to host the angular files on their own servers, have to navigate to https://code.angularjs.org/  and download all necessary scripts manually.

Code available as Gist 

Link : 

Rapid Application Prototyping in PHP Using a Micro Framework (Silex) — Part2 Basic Concepts May 27, 2014

Posted by tournasdimitrios1 in Silex.
Tags: ,
add a comment

Silex framework logoWelcome back to the next part of the article series “Rapid Application Prototyping in PHP Using a Micro Framework (Silex)”. Understanding the basic concepts of this  framework (Silex) will make  you feel more comfortable and confident while using it . The goal of this article is to give you a high-level overview of how the Silex framework “works”. Internally, the Silex core is built on top of Pimple, a Dependency Injection Container, and a few components of the Symfony Framework. One of those components is the HttpFoundation component, which defines an object-oriented layer for the HTTP specification. HTTP has a set of predefined methods (also referred as verbs) to indicate what action should be performed on the identified recourse. Actually we don’t have to worry about HTTP-specifications (and all that boring technical detail) as the browser does all the heavy work behind the scenes to build a request according those specifications. The only thing that really interests us is how we should link a request to the corresponding resource (in technical jargon it is named : Routing). In Silex it’s possible to route in two ways . We can either route to a closure or a controller action. As we’ll be going over controllers in later parts of this article, let’s start by looking at how we can route to a closure . 

Typically, browsers support only three verbs (methods) of the HTTP-specification : HEAD , GET and POST. Developers have invented a nice trick to emulate a couple other verbs (read more on the documentation page) .

When users click on a link or enters a URL in their address bar, they’re creating a GET request.When users submit a form, they’re typically creating a POST request. The browser starts to communicate with the server with a HEAD request .

(more…)

Rapid Application Prototyping in PHP Using a Micro Framework (Silex) — Part1 Introduction May 22, 2014

Posted by tournasdimitrios1 in Silex.
Tags: ,
add a comment

Silex framework logoSetting up a Framework up to the point of a working web application isn’t difficult these days. We just have to open a terminal and take advantage of Composer’s functionality. Composer will handle the whole process of downloading the required package and its associated dependencies in just a couple minutes. Most popular Frameworks nowadays are distributed via packagist , a Composer package repository, which finds packages and lets Composer know where to get the code from. An important decision has to be made though, which framework should be chosen as a foundation for our web application ? Not a simple question indeed. An American pioneer of computer science (Kenneth Thompson) had proposed the “Unix philosophy” : >>> Building short, simple, clear, modular, and extendable code that can be easily maintained and repurposed by developers other than its creators <<< Many [PHP]frameworks follow the aforementioned philosophy very closely, their components are autonomous blocks of code which can be used by other frameworks as building blocks. A characteristic example is Symfony, its modules are used by many frameworks and libraries.

Silex is a PHP Micro-framework based on Symfony 2  components that has been built to focus on smaller web-applications. Silex handles basic tasks (ie routing , DI) without getting in our way, acting as a great base upon which we can architect the rest of our application. The “Application Class” (core component) of Silex is extending Pimple,  it’s a [small] service container, more formally known as a Dependency Injection Container. If you are new to Pimple, reading up on it is going to be extremely important. Pimple’s documentation is pretty easily to follow. As many other dependency injection containers, Pimple is able to manage two different kind of data: services and  parameters (key/value pairs). Developers familiar with Symfony’s  Service_Container , Laravel’s IoC container or ZF2′  Service_Manager component  will immediately recognize that some features which are inherent in those modules (and are required on large scale applications) are not available “out of the box” in Silex . This framework (Silex) is an excellent tool to build simple web applications, but also, it can be used for software prototyping and for building RESTfull API’s.

“Micro” does not mean that the whole web application has to fit into a single  file, although it certainly can. Nor does it mean that Silex is lacking in functionality. The “micro” in micro-framework means Silex aims to keep the core simple but extensible. Silex won’t make many decisions for us, such as what database to use. Almost everything is configurable by the developer, so that Silex can be everything we need and nothing we don’t. Extending Silex’ functionality is simple as registering one of its build-in ServiceProviders, also, writing our own ServiceProviders (extensions) isn’t difficult to accomplish .

(more…)

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

Posted by tournasdimitrios1 in PHP, Zend Framework 2.
Tags: , ,
add a comment

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

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

Posted by tournasdimitrios1 in Zend Framework 2.
Tags: ,
add a comment

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

Follow

Get every new post delivered to your Inbox.

Join 88 other followers