zend framework 2 - basic components
DESCRIPTION
My presentation for meetphp #5TRANSCRIPT
Zend Framework 2Basic components
name:Mateusz Tymek
age: 26
job: Developer at
Who is this guy?
Zend Framework 2
Zend Framework 1 is great! Why do we need new version?
Zend Framework 2
Zend Framework 1 is great! Why do we need new version? ● ZF1 is inflexible● performance sucks● difficult to learn● doesn't use PHP 5.3 goodies
Zend Framework 2● development started in 2010● latest release is BETA3● release cycle is following the "Gmail" style of
betas● developed on GitHub● no CLA needed anymore!● aims to provide modern, fast web
framework...● ...that solves all problems with its
predecessor
ZF1 ZF2application
configscontrollersmodules views
librarypublic
configmodule
Applicationconfigsrc
ApplicationController
viewpublicvendor
New module system
"A Module is a collection of code and other files that solves a more specific atomic problem of the larger business problem"
moduleApplication
configpublicsrc
ApplicationControllerFormModelService
view
Module classclass Module implements AutoloaderProvider {
public function init(Manager $moduleManager) // module initialization {}
public function getAutoloaderConfig() // configure PSR-0 autoloader
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
'Application' => __DIR__ . '/src/Application ',
)));
}
public function getConfig() // provide module configuration
{
return include __DIR__ . '/config/module.config.php';
}
}
Module configuration
Default: modules/Doctrine/config/module.config.php return array( // connection parameters 'connection' => array( 'driver' => 'pdo_mysql', 'host' => 'localhost', 'port' => '3306', 'user' => 'username', 'password' => 'password', 'dbname' => 'database', ), // driver settings 'driver' => array( 'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver', 'namespace' => 'Application\Entity', ),);
User override: config/autoload/doctrine.local.config.php return array( // connection parameters 'connection' => array( 'host' => 'localhost', 'user' => 'username', 'password' => 'password', 'dbname' => 'database', ), );
Zend\EventManagerWhy do we need aspect-oriented programming?
Zend\EventManager
Define your events Zend\Module\Manager ● loadModules.pre● loadModule.resolve● loadModules.post
Zend\Mvc\Application ● bootstrap● route● dispatch● render● finish
Zend\EventManager
Attach event listeners
class Module implements AutoloaderProvider{ public function init(Manager $moduleManager) { $events = $moduleManager->events(); $sharedEvents = $events->getSharedManager();
$sharedEvents->attach( 'Zend\Mvc\Application', 'finish', function(Event $e) {
echo memory_get_usage(); });
}}
Example: blog engineclass BlogEngine { public $events;
public $blogPost;
public function __construct() { $this->events = new EventManager(__CLASS__); }
public function showBlogPost() { $this->events->trigger('render', $this); echo $this->blogPost; }}
Example: blog engineclass BlogEngine { public $events;
public $blogPost;
public function __construct() { $this->events = new EventManager(__CLASS__); }
public function showBlogPost() { $this->events->trigger('render', $this); echo $this->blogPost; }}
// ...$blogEngine->events->attach('render', function($event) { $engine = $event->getTarget(); $engine->blogPost = strip_tags($engine->blogPost); });
Dependency Injection
How do you manage your dependencies?
● globals, singletons, registry
public function indexAction() {global $application;$user = Zend_Auth::getInstance()->getIdentity();$db = Zend_Registry::get('db');
}
Dependency Injection
How do you manage your dependencies?
● Zend_Application_Bootstrap
public function _initPdo() {$pdo = new PDO(...);return $pdo;
}
public function _initTranslations() {$this->bootstrap('pdo');$pdo = $this->getResource('pdo'); // dependency!$stmt = $pdo->prepare('SELECT * FROM translations');// ...
}
Solution: Zend\Di
● First, let's consider simple service class:
class UserService {protected $pdo; public function __construct($pdo) {
$this->pdo = $pdo; }
public function fetchAll() {$stmt = $this->pdo->prepare('SELECT * FROM users');$stmt->execute();return $stmt->fetchAll();
}}
Solution: Zend\Di
● Wire it with PDO, using DI configuration:
return array( 'di' => array( 'instance' => array( 'PDO' => array( 'parameters' => array( 'dsn' => 'mysql:dbname=test;host=127.0.0.1', 'username' => 'root', 'passwd' => '' )),
'UserService' => array( 'parameters' => array( 'pdo' => 'PDO' )
)));
Solution: Zend\Di
● Use it from controllers:
public function indexAction() {
$sUsers = $this->locator->get('UserService');
$listOfUsers = $sUsers->fetchAll();
}
Definitions can be complex.return array(
'di' => array(
'instance' => array(
'Zend\View\Renderer\PhpRenderer' => array(
'parameters' => array(
'resolver' => 'Zend\View\Resolver\AggregateResolver',
),
),
'Zend\View\Resolver\AggregateResolver' => array(
'injections' => array(
'Zend\View\Resolver\TemplateMapResolver',
'Zend\View\Resolver\TemplatePathStack',
),
),
// Defining where the layout/layout view should be located
'Zend\View\Resolver\TemplateMapResolver' => array(
'parameters' => array(
'map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
),
),
// ...
This could go on and on...
Solution: Zend\ServiceLocator
Simplified application config:
return array( 'view_manager' => array( 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_path_stack' => array( 'application' => __DIR__ . '/../view', ), ),);
What about performance?
● PSR-0 loader
● cache where possible
● DiC
● accelerator modules:
EdpSuperluminal, ZfModuleLazyLoading
More info
● http://zendframework.com/zf2/ ● http://zend-framework-community.634137.n4.
nabble.com/ ● https://github.com/zendframework/zf2 ● http://modules.zendframework.com/ ● http://mwop.net/blog.html
Thank you!