Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat....
Transcript of Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat....
![Page 1: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/1.jpg)
Zend Framework 2Rob Allen
PHPNW October 2011
twitter: @akrabat
![Page 2: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/2.jpg)
The experiment
![Page 3: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/3.jpg)
Agenda
• The state of ZF2
• ZF2 foundations
• A look at a ZF2 MVC application
![Page 4: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/4.jpg)
The state of ZF2
![Page 5: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/5.jpg)
“The primary thrust of ZF 2.0 is to make a more consistent, well-documented product, improving
developer productivity and runtime performance.”Matthew Weier O’Phinney
![Page 6: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/6.jpg)
• PHP 5.3 & namespaces
• Interfaces over abstract classes
• Faster autoloader
• Consistent plugin loading
• DI & service locator
• Event manager
• New MVC system
![Page 7: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/7.jpg)
Pace of development
![Page 8: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/8.jpg)
When?
![Page 9: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/9.jpg)
I still have no idea!
![Page 10: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/10.jpg)
ZF2 foundations
![Page 11: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/11.jpg)
Namespaces
![Page 12: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/12.jpg)
Namespaces are a way of encapsulating items
PHP Manual
![Page 13: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/13.jpg)
Namespaces allow us to
• combine libraries with the same class names
• avoid very long class names
• organise our code easily
(They also affect functions and constants)
![Page 14: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/14.jpg)
Defining a namespacenamespace My\Db\Statement;
class Sqlsrv{}
namespace My\Db\Statement;
echo __NAMESPACE__;
Namespace constant:
![Page 15: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/15.jpg)
Namespaces
namespace My\Db\Statement;
function testSqlsrv() {! $stmt = new Sqlsrv ();}
$stmt = new \My\Db\Statement\Sqlsrv();Fully qualified:
Within namespace:
![Page 16: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/16.jpg)
Import
use My\Db\Statement\Sqlsrv;$stmt = new Statement\Sqlsrv();
use My\Db\Statement;use My\Db\Adapter;
$stmt = new Statement\Sqlsrv();$adapter = new Adapter\Sqlsrv();
Multiple namespaces:
Specific class:
![Page 17: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/17.jpg)
Import
use Zend\Db\Statement\Sqlsrv;use Zend\Db\Adapter\Sqlsrv;
$stmt = new Sqlsrv ();$adapter = new Sqlsrv ();
You can’t do this!
![Page 18: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/18.jpg)
Aliases
use My\Db\Statement\Sqlsrv as DbStatement;use My\Db\Adapter\Sqlsrv as DbAdapter;
$stmt = new DbStatement ();$adapter = new DbAdapter();
Solve with aliases:
![Page 19: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/19.jpg)
Namespace resolution
• The current namespace is prepended to the function name.
• If the function names doesn't exists in the current namespace, then a global function name is used if it exists.
An unqualified function name is resolved in this order:
$date = date('Y-m-d');
![Page 20: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/20.jpg)
Namespace resolution
• If there is an import statement that aliases another name to this class name, then the alias is applied.
• Otherwise the current namespace is applied.
An unqualified class name is resolved in this order:
$dateTime = new \DateTime();
![Page 21: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/21.jpg)
Autoloader
![Page 22: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/22.jpg)
Autoloading allows files to be automatically included at the
last minute.
zendcoding.com
![Page 23: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/23.jpg)
Zend\Loader\Autoloader
• Class map autoloading, including class map generation
• PSR-0-compliant per-prefix or namespace autoloading
• Fallback PSR-0-compliant include_path autoloading
• Autoloader factory for loading several autoloader strategies at once
![Page 24: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/24.jpg)
PSR-0?
A standard that describes how to name a class so that the autoloader can find it.Essentially each namespace maps directly to a folder on disk:i.e.
\Zend\Config\Ini should be found in /path/to/Zend/Config/ini.php
![Page 25: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/25.jpg)
StandardAutoloader
• Inspects classname and finds file on disk
• Load via namespace => directory pairs
• Load via prefix => directory pairs
• Fallback search of include_path
![Page 26: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/26.jpg)
StandardAutoloaderrequire_once ZF2_PATH.'/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader(array( 'prefixes' => array( 'MyVendor' => __DIR__ . '/MyVendor', ), 'namespaces' => array( 'MyNamespace' => __DIR__ . '/MyNamespace', ), 'fallback_autoloader' => true,));
// register our loader with the SPL autoloader$loader->register();
![Page 27: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/27.jpg)
StandardAutoloaderrequire_once ZF2_PATH.'/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader();
$loader->registerPrefix('MyVendor', __DIR__.'/MyVendor') ->registerNamespace('MyNamespace', __DIR__.'/MyNamespace') ->setFallbackAutoloader(true);
// register our loader with the SPL autoloader$loader->register();
![Page 28: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/28.jpg)
ClassMapAutoloader
• Array of class name to file on disk
• High performance!
public function autoload($class){ if (isset($this->map[$class])) { include $this->map[$class]; }}
![Page 29: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/29.jpg)
A class map
use My\Db\Statement\Sqlsrv;$stmt = new Statement\Sqlsrv();
require_once ZF2_PATH.'/Loader/ClassMapAutoloader.php';
$autoLoader = new \Zend\Loader\ClassMapAutoloader( array(__DIR__ . '/autoload_classmap.php'));
// register with the SPL autoloader$autoLoader->register();
Using:
autoload_classmap.php:
![Page 30: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/30.jpg)
Multiple class maps$loader = new \Zend\Loader\ClassMapAutoloader(array( __DIR__ . '/../library/autoload_classmap.php', __DIR__ . '/../application/autoload_classmap.php',));
OR:
$loader = new \Zend\Loader\ClassMapAutoloader();$loader->registerAutoloadMap(array( __DIR__ . '/../library/autoload_classmap.php', __DIR__ . '/../application/autoload_classmap.php',));
![Page 31: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/31.jpg)
Creating classmapsprompt> php path/to/zf2/bin/classmap_generator.php -wCreating class file map for library in '/var/www/project/library'...Wrote classmap file to '/var/www/project/library/autoload_classmap.php'
![Page 32: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/32.jpg)
Combining autoloaders
• Use class maps and the prefixes!
• Very useful in development
• Use ZF2’s AutoloaderFactory class
![Page 33: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/33.jpg)
require_once ZF2_PATH . '/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory(array( 'Zend\Loader\ClassMapAutoloader' => array( __DIR__ . '/../library/Zend/autoload_classmap.php', ), 'Zend\Loader\StandardAutoloader' => array( 'prefixes' => array( 'MyVendor' => __DIR__ . '/MyVendor', ), 'namespaces' => array( 'MyNamespace' => __DIR__ . '/MyNamespace', ), 'fallback_autoloader' => true, ),));
![Page 34: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/34.jpg)
Autoloader summary
• Use the class map one in preference as it’s really really fast!
• Prefix => directory pairs is surprisingly fast though compared to ZF1
![Page 35: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/35.jpg)
Exercise
Update the ZF1 Tutorial to use the Autoloader from ZF2:1. Using StandardAutoloader2. Using a classmap for library code and a
StandardAutoloader for the application code.
![Page 36: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/36.jpg)
Dependency Injection
![Page 37: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/37.jpg)
Dependency injection means giving an object its instance variables. Really. That's it.
James Shore
![Page 38: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/38.jpg)
Contrived exampleclass Album { protected $artist; public function getArtistName() { return $artist->getName(); }}
![Page 39: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/39.jpg)
How do we set the $artist member variable?
![Page 40: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/40.jpg)
Direct instantiationclass Album { protected $artist; public function __construct() { $this->artist = new Artist(); } // etc}
![Page 41: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/41.jpg)
Constructor injectionclass Album { protected $artist; public function __construct(Artist $artist) { $this->artist = $artist; } // etc}
Calling code:$album = new Album($artist);
![Page 42: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/42.jpg)
Constructor injectionclass Album { protected $artist; public function __construct(Artist $artist) { $this->artist = $artist; } // etc}
Calling code:$album = new Album($artist);
![Page 43: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/43.jpg)
Setter injectionclass Album { protected $artist; public function setArtist(Artist $artist) { $this->artist = $artist; } // etc}
Calling code:$album = new Album();$album->setArtist($artist);
![Page 44: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/44.jpg)
Advantages
• Can use different objects (e.g. SoloArtist)
• Configuration is natural
• Testing is simplified
• Do not need to change the Album class
DisadvantagesInstantiation and configuration of a class’ dependencies are the responsibility of the calling code.
![Page 45: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/45.jpg)
Dependency Injection Container
class AlbumContainer { public static $artist; public static function createAlbum() { $album = new Album(); $album->setArtist(self::$artist); // more setXxx() calls here as required return $album; }}
Calling code:$album = AlbumContainer::createAlbum();
![Page 46: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/46.jpg)
A dependency injection container is a component that holds dependency definitions and instantiates them for you.
![Page 47: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/47.jpg)
Zend\Di
• Supports constructor and setter injection
• Configured in code or via config file
• Type hinting makes life easier
![Page 48: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/48.jpg)
Constructor injectionnamespace My;
class Artist{}
class Album{ protected $artist = null; public function __construct (Artist $artist) { $this->artist = $artist; }}
![Page 49: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/49.jpg)
To use an $album:$di = new Zend\Di\DependencyInjector();$album = $di->get('My\Album');
Also:$album2 = $di->newInstance('My\Album');
![Page 50: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/50.jpg)
Parameters in dependenciesclass Artist{ protected $name; public function __construct($name) { $this->name = $name; }}
Use setParameters:$di = new Zend\Di\DependencyInjector();$di->getInstanceManager()! ->setParameters('Artist', array('name' => 'Queen'));
![Page 51: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/51.jpg)
Parameters in dependencies
Usage:$album = $di->get('My\Album');
Set at call time:$album = $di->get('My\Album', array('name'=>'Jonathan Coulton'));
![Page 52: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/52.jpg)
Setter injectionnamespace My;class Artist{ protected $name; public function __construct($name) { $this->name = $name; }}
class Album{ protected $artist = null; public function setArtist(Artist $artist) { $this->artist = $artist; }}
![Page 53: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/53.jpg)
To use an $album:
Enable:$di->getDefinition()->getIntrospectionRuleset() ->addSetterRule('paramCanBeOptional', false);
Use:$album = $di->get('My\Album', array('name'=>'Train'));
![Page 54: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/54.jpg)
Definitions
• RuntimeDefinition
• Resolves at runtime (reflection-based)
• BuilderDefinition
• Programmatic creation via Builder\PhpClass
• ArrayDefinition
• Dependencies defined in an array
• AggregateDefinition
• Combine different definitions
![Page 55: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/55.jpg)
BuilderDefinitionuse Zend\Di\DependencyInjector, Zend\Di\Definition, Zend\Di\Definition\Builder;
// Builder definition for My\Album$method = new Builder\InjectionMethod();$method->setName('setArtist');$method->addParameter('artist', 'My\Artist');
$class = new Builder\PhpClass();$class->setName('My\Album');$class->addInjectionMethod($method); $builderDef = new Definition\BuilderDefinition();$builderDef->addClass($class);
$di = new DependencyInjector();$di->setDefinition($builderDef);
![Page 56: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/56.jpg)
Compilation to ArrayDefinitionuse Zend\Di,! Zend\Code\Scanner\ScannerDirectory;
$compiler = new Di\Definition\Compiler();$compiler->addCodeScannerDirectory( new ScannerDirectory('path/to/library/My/'));$definition = $compiler->compile();
$di = new Di\DependencyInjector();$di->setDefinition($definition);$album = $di->get('My\Album', array('Oasis'));
![Page 57: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/57.jpg)
Persistancefile_put_contents( __DIR__ . '/di-definition.php', '<?php return ' . var_export($definition->toArray(), true) . ';');
Load:$definition = new Zend\Di\Definition\ArrayDefinition( include __DIR__ . '/di-definition.php');
![Page 58: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/58.jpg)
Aliases
• Makes it easier to specify dependencies
• Can retrieve from the injector by alias too.
$di = new Zend\Di\DependencyInjector();$im = $di->getInstanceManager();
$im->addAlias('artist', 'My\Artist');$im->addAlias('album', 'My\Album');
$im->setParameters('artist', array('name' => 'Blur'));
$artist = $di->get("artist");$album = $di->get("album", array("name" => "Queen"));
![Page 59: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/59.jpg)
Configuration
Config file:[production]di.instance.alias.album = 'My\Album'di.instance.alias.artist = 'My\Artist'
di.instance.artist.parameters.name = 'Marillion'
PHP file:use Zend\Config, Zend\Di;$config = new Config\Ini('application.ini', 'dev');$diConfig = new Di\Configuration($config->di);
$di = new Di\DependencyInjector($diConfig);$artist = $di->get("artist");$album = $di->get("album", array("name" => "Queen"));
![Page 60: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/60.jpg)
Aggregationuse Zend\Di\Definition;
$arrayDef = new Definition\ArrayDefinition( include __DIR__ . '/di-definition.php');
$runtimeDef = new Definition\RuntimeDefinition();
// Aggregate the two definitions$aggregateDef = new Definition\AggregateDefinition();$aggregateDef->addDefinition($arrayDef);$aggregateDef->addDefinition($runtimeDef);
$di = new \Zend\Di\DependencyInjector();$di->setDefinition($aggregateDef);
![Page 61: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/61.jpg)
DI summary
• DI allows defining dependencies independent of the calling code
• You still need to wire things up - it’s just all in one place with DIC.
• This is used extensively in the MVC system
![Page 62: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/62.jpg)
Event Manager
![Page 63: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/63.jpg)
Event Manager allows a class to publish events which other
components can listen for and act when that event occurs.
Me!
![Page 64: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/64.jpg)
Terminology
• An Event Manager is an object that aggregates listeners for one or more named events, and which triggers events.
• A Listener is a callback that can react to an event.
• An Event is an action.
• A Target is an object that creates events
(Shameless stolen from Matthew Weier O’Phinney!)
![Page 65: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/65.jpg)
Simple exampleuse Zend\EventManager\EventManager, Zend\EventManager\Event;
$callback = function($event) { echo "An event has happened!\n"; var_dump($event->getName()); var_dump($event->getParams()); };
$eventManager = new EventManager();$eventManager->attach('eventName', $callback);
echo "\nRaise an event\n";$eventManager->trigger('eventName', null, array('one'=>1, 'two'=>2));
![Page 66: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/66.jpg)
Targetuse Zend\EventManager\EventManager, Zend\EventManager\Event;class MyTarget{ public $eventManager; public function __construct() { $this->eventManager = new EventManager(); } public function doIt() { $event = new Event(); $event->setTarget($this); $event->setParam('one', 1); $event->setParam('two', 2); $this->eventManager->trigger('doIt.pre', $event); }}
![Page 67: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/67.jpg)
Target$callback = function ($event) { echo "Responding to doIt.pre!\n"; var_dump(get_class($event->getTarget())); var_dump($event->getName()); var_dump($event->getParams());};
$target = new MyTarget();$target->eventManager->attach('doIt.pre', $callback);$target->doIt();
![Page 68: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/68.jpg)
StaticEventManagerclass MyTarget{ public $eventManager; public function __construct() { $this->eventManager = new EventManager(__CLASS__); } // etc}
// attach a listeneruse Zend\EventManager\StaticEventManager;$events = StaticEventManager::getInstance();$events->attach('MyTarget', 'doIt.pre', $callback);
// cause event to trigger$target->doIt();
![Page 69: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/69.jpg)
StaticEventManager
• Statically attached listeners are called after the directly attached ones.
• The identifier can be an array:$this->eventManager = new EventManager( array(__CLASS__, get_called_class()));
Allows for attaching to generic parent class or specific child
• Disable statically attached listeners:$this->eventManager->setStaticConnections(null);
• Re-enable:$this->eventManager->setStaticConnections( StaticEventManager::getInstance());
![Page 70: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/70.jpg)
Listener aggregates
• HandlerAggregate interface provides for attaching and detaching event listeners
• Two methods:
• attach(EventCollection $events)
• detach(EventCollection $events)
• (EventCollection is the interface that EventManager implements)
![Page 71: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/71.jpg)
Using HandlerAggregateclass MyListener implements HandlerAggregate{ protected $eventHandlers = array(); public function attach(EventCollection $events) { $this->handlers[] = $events->attach('event1', array($this, 'doSomething')); $this->handlers[] = $events->attach('event2', array($this, 'doSomethingElse')); } public function detach(EventCollection $events) { foreach ($this->handlers as $key => $handler) { $events->detach($handler); unset($this->handlers[$key]); } $this->handlers = array(); }
![Page 72: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/72.jpg)
Using HandlerAggregate$target = new MyTarget();
// Attach the target's event manager to the listener$listener = new MyListener();$listener->attach($target->getEventManager());
// Now we can trigger some events$target->doSomething();$target->doSomethingElse();
// Detach$listener->detach($target->getEventManager());
// this trigger will not fire the listener’s$target->doSomething();
![Page 73: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/73.jpg)
Returned values from listenerspublic function triggerEvent1(){ $results = $this->eventManager->trigger('event1', $this); foreach ($results as $result) { var_dump($result); }}
• $results is a ResponseCollection
• $results are in reverse order (latest triggered event is first)
![Page 74: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/74.jpg)
Short-circuitingpublic function triggerEvent1(){ $results = $this->eventManager->trigger('event1', $this); foreach ($results as $result) { var_dump($result); }}
• $results is a ResponseCollection
• $results are in reverse order (latest triggered event is first)
![Page 75: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/75.jpg)
Short-circuitingpublic function doIt(){ $params = array('id' => 1); $results = $this->eventManager->trigger('doIt.pre', $this, $params, function ($result) { if($result == 'done') { return true; } return false; } ); if ($results->stopped()) { // We ended early }}
![Page 76: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/76.jpg)
Priority
• Control the order of execution of listeners
• $priority is last parameter to attach()$eventManager->attach('doIt.pre', $callback, $priority);
• Default is 1
• Larger increases priority
• Smaller decreases priority
![Page 77: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/77.jpg)
EventManager summary
• Decouples objects from one another
• Increases flexibility
• Expect to use in MVC system
![Page 78: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/78.jpg)
Exercise
Using the ZF2 EventManager, add logging to Application_Models_DbTable_Albums
(I have created Application_Model_Logger as a starting point for you...)
![Page 79: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/79.jpg)
A ZF2 Application
![Page 80: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/80.jpg)
This is very much PROTOTYPE code
![Page 81: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/81.jpg)
![Page 82: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/82.jpg)
Exercise
Use the ZF2 Skeleton Application and Skeleton Module to create a website that displays a random quote on the home page.
![Page 83: Zend Framework 2 - akrabat.com · Zend Framework 2 Rob Allen PHPNW October 2011 twitter: @akrabat. The experiment. Agenda • The state of ZF2 • ZF2 foundations • A look at a](https://reader034.fdocuments.in/reader034/viewer/2022042303/5ece90c71c65d25c5728d4c0/html5/thumbnails/83.jpg)
Resources
• http://framework.zend.com/zf2
• https://github.com/akrabat/zf2-tutorial
• https://github.com/zendframework/ZendSkeletonApplication
• https://github.com/zendframework/ZendSkeletonModule
• https://github.com/weierophinney/zf-quickstart/tree/features/zf2-mvc-module