Zend Framework 2
Basic components
Who is this guy?
name:
     Mateusz Tymek
age:
     26
job:
     Developer at
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             ZF2
application     config
  configs       module
  controllers     Application
  modules            config
  views              src
library                Application
public                    Controller
                     view
                public
                vendor
New module system
module
  Application
     config            "A Module is a
     public            collection of code and
     src
       Application
                       other files that solves
          Controller
                       a more specific
          Form         atomic problem of the
          Model        larger business
          Service      problem"
     view
Module class
class Module implements AutoloaderProvider {
        public function init(Manager $moduleManager)   // module initialization
        {}


        public function getAutoloaderConfig()   // configure PSR-0 autoloader
        {
            return array(
               'ZendLoaderStandardAutoloader' => array(
                    'namespaces' => array(
                        'Application' => __DIR__ . '/src/Application ',
                    )));
        }


        public function getConfig() // provide module configuration
        {
            return include __DIR__ . '/config/module.config.php';
        }
    }
Module configuration

Default:                                          User override:

modules/Doctrine/config/module.config.php         config/autoload/doctrine.local.config.php

return array(                                     return array(
   // connection parameters                           // connection parameters
   'connection' => array(                             'connection' => array(
       'driver'   => 'pdo_mysql',                         'host'     => 'localhost',
       'host'     => 'localhost',                         'user'     => 'username',
       'port'     => '3306',                              'password' => 'password',
       'user'     => 'username',                          'dbname'   => 'database',
       'password' => 'password',                      ),
       'dbname'   => 'database',                  );
   ),
   // driver settings
   'driver' => array(
       'class'     =>
'DoctrineORMMappingDriverAnnotationDriver',
       'namespace' => 'ApplicationEntity',
      ),
);
ZendEventManager
Why do we need aspect-oriented
programming?
ZendEventManager

Define your events

ZendModuleManager    ZendMvcApplication

● loadModules.pre      ●   bootstrap
● loadModule.resolve   ●   route
● loadModules.post     ●   dispatch
                       ●   render
                       ●   finish
ZendEventManager

Attach event listeners
class Module implements AutoloaderProvider
{
    public function init(Manager $moduleManager)
    {
        $events       = $moduleManager->events();
        $sharedEvents = $events->getSharedManager();

        $sharedEvents->attach(
              'ZendMvcApplication', 'finish',
               function(Event $e) {
                    echo memory_get_usage();
               });
    }
}
Example: blog engine
class 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 engine
class 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: ZendDi

● 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: ZendDi

● 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: ZendDi

● 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(
           'ZendViewRendererPhpRenderer' => array(
                'parameters' => array(
                     'resolver' => 'ZendViewResolverAggregateResolver',
                ),
           ),
           'ZendViewResolverAggregateResolver' => array(
                'injections' => array(
                     'ZendViewResolverTemplateMapResolver',
                     'ZendViewResolverTemplatePathStack',
                ),
           ),
           // Defining where the layout/layout view should be located
           'ZendViewResolverTemplateMapResolver' => array(
                'parameters' => array(
                     'map'   => array(
                          'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
                     ),
                ),
           // ...




                                                                 This could go on and on...
Solution: ZendServiceLocator

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!

Zend Framework 2 - Basic Components

  • 1.
  • 2.
    Who is thisguy? name: Mateusz Tymek age: 26 job: Developer at
  • 3.
    Zend Framework 2 ZendFramework 1 is great! Why do we need new version?
  • 4.
    Zend Framework 2 ZendFramework 1 is great! Why do we need new version? ● ZF1 is inflexible ● performance sucks ● difficult to learn ● doesn't use PHP 5.3 goodies
  • 5.
    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
  • 6.
    ZF1 ZF2 application config configs module controllers Application modules config views src library Application public Controller view public vendor
  • 7.
    New module system module Application config "A Module is a public collection of code and src Application other files that solves Controller a more specific Form atomic problem of the Model larger business Service problem" view
  • 8.
    Module class class Moduleimplements AutoloaderProvider { public function init(Manager $moduleManager) // module initialization {} public function getAutoloaderConfig() // configure PSR-0 autoloader { return array( 'ZendLoaderStandardAutoloader' => array( 'namespaces' => array( 'Application' => __DIR__ . '/src/Application ', ))); } public function getConfig() // provide module configuration { return include __DIR__ . '/config/module.config.php'; } }
  • 9.
    Module configuration Default: User override: modules/Doctrine/config/module.config.php config/autoload/doctrine.local.config.php return array( return array( // connection parameters // connection parameters 'connection' => array( 'connection' => array( 'driver' => 'pdo_mysql', 'host' => 'localhost', 'host' => 'localhost', 'user' => 'username', 'port' => '3306', 'password' => 'password', 'user' => 'username', 'dbname' => 'database', 'password' => 'password', ), 'dbname' => 'database', ); ), // driver settings 'driver' => array( 'class' => 'DoctrineORMMappingDriverAnnotationDriver', 'namespace' => 'ApplicationEntity', ), );
  • 10.
    ZendEventManager Why do weneed aspect-oriented programming?
  • 11.
    ZendEventManager Define your events ZendModuleManager ZendMvcApplication ● loadModules.pre ● bootstrap ● loadModule.resolve ● route ● loadModules.post ● dispatch ● render ● finish
  • 12.
    ZendEventManager Attach event listeners classModule implements AutoloaderProvider { public function init(Manager $moduleManager) { $events = $moduleManager->events(); $sharedEvents = $events->getSharedManager(); $sharedEvents->attach( 'ZendMvcApplication', 'finish', function(Event $e) { echo memory_get_usage(); }); } }
  • 13.
    Example: blog engine classBlogEngine { public $events; public $blogPost; public function __construct() { $this->events = new EventManager(__CLASS__); } public function showBlogPost() { $this->events->trigger('render', $this); echo $this->blogPost; } }
  • 14.
    Example: blog engine classBlogEngine { 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); });
  • 15.
    Dependency Injection How doyou manage your dependencies? ● globals, singletons, registry public function indexAction() { global $application; $user = Zend_Auth::getInstance()->getIdentity(); $db = Zend_Registry::get('db'); }
  • 16.
    Dependency Injection How doyou 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'); // ... }
  • 17.
    Solution: ZendDi ● 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(); } }
  • 18.
    Solution: ZendDi ● Wireit 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' ) )));
  • 19.
    Solution: ZendDi ● Useit from controllers: public function indexAction() { $sUsers = $this->locator->get('UserService'); $listOfUsers = $sUsers->fetchAll(); }
  • 20.
    Definitions can becomplex. return array( 'di' => array( 'instance' => array( 'ZendViewRendererPhpRenderer' => array( 'parameters' => array( 'resolver' => 'ZendViewResolverAggregateResolver', ), ), 'ZendViewResolverAggregateResolver' => array( 'injections' => array( 'ZendViewResolverTemplateMapResolver', 'ZendViewResolverTemplatePathStack', ), ), // Defining where the layout/layout view should be located 'ZendViewResolverTemplateMapResolver' => array( 'parameters' => array( 'map' => array( 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', ), ), // ... This could go on and on...
  • 21.
    Solution: ZendServiceLocator Simplified applicationconfig: return array( 'view_manager' => array( 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_path_stack' => array( 'application' => __DIR__ . '/../view', ), ), );
  • 22.
    What about performance? ● PSR-0 loader ● cache where possible ● DiC ● accelerator modules: EdpSuperluminal, ZfModuleLazyLoading
  • 23.
    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
  • 24.