SlideShare ist ein Scribd-Unternehmen logo
1 von 61
Zend Framework 2 Patterns
Matthew Weier O'Phinney
Project Lead, Zend Framework


To watch the webinar please go to:
http://www.zend.com/en/webinar/Framework/70170000000bX3J-
webinar-zf-2-patterns-20110330.flv


                                                © All rights reserved. Zend Technologies, Inc.
Roadmap for today
●   Namespaces and Autoloading
●   Exceptions
●   Configuration
●   Plugin systems
●   Dispatching
●   Inversion of Control




                     © All rights reserved. Zend Technologies, Inc.
Format
●   List The Problems
●   Detail the ZF2 Approach




                    © All rights reserved. Zend Technologies, Inc.
But first, some history




     © All rights reserved. Zend Technologies, Inc.
Zend Framework 1.X
●   1.0 Released in July 2007
●   Largely evolutionary development
    ▶   Inconsistencies in APIs, particularly surrounding
        plugins and configuration
    ▶   Best practices have been discovered over time
    ▶   Many key features for modern applications have
        been added in recent versions




                         © All rights reserved. Zend Technologies, Inc.
Zend Framework 2.0
●   First new major release
    ▶   Allowing us to break backwards compatibility
●   Focus is on:
    ▶   Consistency
    ▶   Performance
    ▶   Documentation
    ▶   User productivity




                        © All rights reserved. Zend Technologies, Inc.
Namespaces and Autoloading




7          © All rights reserved. Zend Technologies, Inc.
The Problems
●   Lengthy class names
    ▶   Difficult to refactor
    ▶   Difficult to retain semantics with shorter names
●   Performance issues
    ▶   Many classes are used JIT, and shouldn't be loaded
        until needed
●   Missing require_once statements lead to errors




                          © All rights reserved. Zend Technologies, Inc.
ZF2 Approach: Namespaces
●   Formalize the prefixes used in ZF1
    ▶   Namespace separator correlates to directory
        separator
●   Help identify dependencies (imports)
    ▶   Allows refactoring using different implementations
        easier
    ▶   Makes packaging easier




                        © All rights reserved. Zend Technologies, Inc.
Namespaces


namespace ZendEventManager;

use ZendStdlibCallbackHandler;

class EventManager implements EventCollection
{
    /* ... */
}




                   © All rights reserved. Zend Technologies, Inc.
Namespaces
●   Interfaces as namespaces
    ▶   Interface names are adjectives or nouns
    ▶   Concrete implementations in a sub-namespace
        named after the interface
    ▶   Contract-Oriented paradigm




                        © All rights reserved. Zend Technologies, Inc.
Interfaces as Namespaces
Zend/Session              namespace ZendSession;
|-- Storage.php           interface Storage
`-- Storage
                          {
    |--
                              /* ... */
ArrayStorage.php
                          }
    `--
SessionStorage.php
namespace ZendSessionStorage;
use ArrayObject,
    ZendSessionStorage,
    ZendSessionException;
class ArrayStorage
    extends ArrayObject
    implements Storage
{ /* ... */ }
                   © All rights reserved. Zend Technologies, Inc.
ZF2 Approach: Autoloading
●   No more require_once calls!
●   Multiple approaches
    ▶   ZF1-style include_path autoloader
    ▶   Per-namespace/prefix autoloading
    ▶   Class-map autoloading




                        © All rights reserved. Zend Technologies, Inc.
ZF1-Style Autoloading



require_once
'Zend/Loader/StandardAutoloader.php';
$loader =
    new ZendLoaderStandardAutoloader(array(
    'fallback_autoloader' => true,
));
$loader->register();




                   © All rights reserved. Zend Technologies, Inc.
ZF2 NS/Prefix Autoloading


require_once
'Zend/Loader/StandardAutoloader.php';
$loader = new ZendLoaderStandardAutoloader();
$loader->registerNamespace(
            'My', __DIR__ . '/../library/My')
       ->registerPrefix(
            'Phly_', __DIR__ .
'/../library/Phly');
$loader->register();




                   © All rights reserved. Zend Technologies, Inc.
ZF2 Class-Map Autoloading

return array(
    'MyFooBar' => __DIR__ . '/Foo/Bar.php',
);



require_once
'Zend/Loader/ClassMapAutoloader.php';
$loader = new ZendLoaderClassMapAutoloader();
$loader->registerAutoloadMap(
    __DIR__ . '/../library/.classmap.php');
$loader->register();



                   © All rights reserved. Zend Technologies, Inc.
Exceptions




17   © All rights reserved. Zend Technologies, Inc.
The Problems
●   All exceptions derived from a common class
●   No ability to extend more semantic exception
    types offered in SPL




                    © All rights reserved. Zend Technologies, Inc.
ZF2 Approach
●   Eliminated Zend_Exception
●   Each component defines a marker Exception
    interface
●   Additional exception types are created in an
    Exception subnamespace
    ▶   These extend SPL exceptions, and implement the
        component-level exception interface




                       © All rights reserved. Zend Technologies, Inc.
What the solution provides
●   Catch specific exception types
●   Catch SPL exception types
●   Catch any component-level exception
●   Catch based on global exception type




                     © All rights reserved. Zend Technologies, Inc.
Exceptions in use
Zend/EventManager                               namespace
|-- Exception.php                               ZendEventManager;
`-- Exception
    `-- InvalidArgument-                        interface Exception {}
        Exception.php



namespace ZendEventManagerException;

use ZendEventManagerException;

class InvalidArgumentException
    extends InvalidArgumentException
    implements Exception
{}


                     © All rights reserved. Zend Technologies, Inc.
Exceptions in use

namespace ZendEventManagerException;
use ZendEventManagerException;
try {
    $events->trigger('foo.bar', $object);
} catch (InvalidArgumentException $e) {
} catch (Exception $e) {
} catch (InvalidArgumentException $e) {
} catch (Exception $e) {
}




                    © All rights reserved. Zend Technologies, Inc.
Configuration




23   © All rights reserved. Zend Technologies, Inc.
The Problems
●   Case-SeNSItiviTy
●   Varying APIs
    ▶   setOptions()
    ▶   setConfig()
    ▶   __construct()
    ▶   explicit setters




                           © All rights reserved. Zend Technologies, Inc.
ZF2 Approach
●   Option names will be
    lowercase_underscore_separated_word
    s
●   Standard solution across components
    ▶   setOptions() style, proxying to setters, or
    ▶   per-component configuration objects




                        © All rights reserved. Zend Technologies, Inc.
setOptions() style
class Foo
{
    public function setOptions($options)
    {
        if (!is_array($options)
            && !($options instanceof
Traversable)
        ) {
            throw new
InvalidArgumentException();
        }

       foreach ($options as $key => $value) {
           $method = normalize($key);
           if (method_exists($this, $method)) {
               $this->$method($value);
           }
       }           © All rights reserved. Zend Technologies, Inc.
Options object style
class FooOptions extends Options
{
    public $bar;
    public $baz;

    public function __construct($options = null)
    {
        if (!is_array($options)
            && !($options instanceof Traversable)
        ) {
            throw new InvalidArgumentException();
        }

        foreach ($options as $key => $value) {
            $prop = normalize($key);
            $this->$prop = $value;
        }
    }
}                    © All rights reserved. Zend Technologies, Inc.
Options object style


class Foo
{
    public function __construct(Options $options =
null)
    {
        if (null !== $options) {
            foreach ($options as $key => $value) {
                $this->$key = $value;
            }
        }
    }
}



                     © All rights reserved. Zend Technologies, Inc.
Plugin Architectures




29       © All rights reserved. Zend Technologies, Inc.
Terminology
●   For our purposes, a “plugin” is any class that is
    determined at runtime.
    ▶   Action and view helpers
    ▶   Adapters
    ▶   Filters and validators




                         © All rights reserved. Zend Technologies, Inc.
The Problems
●   Varying approaches to dynamically discovering
    plugin classes
    ▶   Prefix-path stacks (most common)
    ▶   Paths relative to the calling class
    ▶   Setters to indicate classes
●   Most common approach is terrible
    ▶   Bad performance
    ▶   Hard to debug
    ▶   No caching of discovered plugins

                          © All rights reserved. Zend Technologies, Inc.
ZF2 Approach: Plugin Broker
●   Separate Plugin Location interface
    ▶   Allows varying implementation of plugin lookup
●   Separate Plugin Broker interface
    ▶   Composes a Plugin Locator




                        © All rights reserved. Zend Technologies, Inc.
ZF2 Approach: Plugin Broker
●   Standard implementation across components
    ▶   Subclassing standard implementation allows type-
        hinting, caching discovered plugins, etc.
    ▶   while allowing you to substitute your own
        implementations
●   Class-map location by default
●   2-5x performance gains!
●   Easier to debug


                        © All rights reserved. Zend Technologies, Inc.
Plugin class location
namespace ZendLoader;

interface ShortNameLocater
{
    public function isLoaded($name);
    public function getClassName($name);
    public function load($name);
}
namespace ZendView;
use ZendLoaderPluginClassLoader;
class HelperLoader extends PluginClassLoader
{
    protected $plugins = array(
        'action' => 'ZendViewHelperAction',
        'baseurl' => 'ZendViewHelperBaseUrl',
        /* ... */
    );
}
                     © All rights reserved. Zend Technologies, Inc.
Plugin broker

namespace ZendLoader;

interface Broker
{
    public function load($plugin, array $options =
null);
    public function getPlugins();
    public function isLoaded($name);
    public function register($name, $plugin);
    public function unregister($name);
    public function setClassLoader(
        ShortNameLocater $loader);
    public function getClassLoader();
}



                     © All rights reserved. Zend Technologies, Inc.
Plugin broker
class HelperBroker extends PluginBroker {
    protected $defaultClassLoader =
'ZendViewHelperLoader';
    protected $view;
    public function setView(Renderer $view) {}
    public function getView() {}
    public function load($plugin, array $options = null) {
        $helper = parent::load($plugin, $options);
        if (null !== ($view = $this->getView())) {
            $helper->setView($view);
        }
        return $helper;
    }
    protected function validatePlugin($plugin)
    {
        if (!$plugin instanceof Helper) {
            throw new InvalidHelperException();
        }
        return true;
    }
}                       © All rights reserved. Zend Technologies, Inc.
ZF2 Approach: Events
●   Trigger events at interesting points in your
    application
    ▶   Use as basic subject/observer pattern
    ▶   Or as intercepting filters
    ▶   Or a full-fledged Aspect-Oriented Programming
        system




                          © All rights reserved. Zend Technologies, Inc.
ZF2 Approach: Events
●   Compose an EventManager to a class
●   Attach handlers to events
    ▶   Handlers receive an Event
         ●   event name
         ●   target (calling) object
         ●   parameters passed
    ▶   Handlers can also be attached statically




                              © All rights reserved. Zend Technologies, Inc.
Triggering an event


public function doSomething(
    $with, $params = array()
) {
    $this->events()->trigger(
        __FUNCTION__, compact('with', 'params')
    );
    /* ... */
}




                   © All rights reserved. Zend Technologies, Inc.
Listening to an event

use ZendEventManagerEventManager as Events;

$events = new Events();
$events->attach('doSomething', function($e) use
($log) {
    $event = $e->getName();
    $target = get_class($e->getTarget());
    $params = json_encode($e->getParams());
    $message = sprintf('%s (%s): %s', $event,
$target, $params);
    $log->info($message);
});




                     © All rights reserved. Zend Technologies, Inc.
Attaching statically to an event


use ZendEventManagerStaticEventManager as
AllEvents;

$events = AllEvents::getInstance();

// Specify the class composing an EventManager
// as first arg
$events->attach('Foo', 'doSomething', function($e)
{});




                     © All rights reserved. Zend Technologies, Inc.
Dispatchers




42   © All rights reserved. Zend Technologies, Inc.
The Problems
●   Not terribly performant
●   Hard to customize
●   Hard to inject controllers with dependencies
●   Forces pre-initialization of resources if you
    want them configured by Zend_Application




                     © All rights reserved. Zend Technologies, Inc.
ZF2 Approach
●   Discrete Request, Response, and Dispatchable
    interfaces
    ▶   Request encompasses request environment
    ▶   Response aggregates response returned
    ▶   Dispatchable objects formalize a Strategy
        pattern




                       © All rights reserved. Zend Technologies, Inc.
ZF2 Approach
●   Anything Dispatchable can be attached to the
    MVC
    ▶   Server components (XML-RPC, JSON-RPC, etc.)
●   Allows building your own MVC approach
    ▶   Do you want action methods to receive explicit
        arguments?
    ▶   Do you want to select a different action method
        based on request headers?



                        © All rights reserved. Zend Technologies, Inc.
MVC Interfaces
interface Message
{
    public function setMetadata($spec, $value =
null);
    public function getMetadata($key = null);
    public function setContent($content);
    public function getContent();
}
interface Request           interface Response
    extends Message             extends Message
{                           {
    public function             public function
        __toString();               __toString();
    public function             public function

fromString($string);                              fromString($string);
}                                                     public function
                                                  send();
                                                  }
                       © All rights reserved. Zend Technologies, Inc.
MVC Interfaces


interface Dispatchable
{
    public function dispatch(
        Request $request,
        Response $response = null);
}




                   © All rights reserved. Zend Technologies, Inc.
Inversion of Control




48      © All rights reserved. Zend Technologies, Inc.
The Problems
●   How do objects get dependencies?
    ▶   In particular, how do Controllers get dependencies?




                         © All rights reserved. Zend Technologies, Inc.
ZF2 Approach
●   Service Locator
    ▶   Basic pattern:
         ●   set($name, $service)
         ●   get($name)
    ▶   Formalization of application services
        (mailer, logger, profiler, etc.)
    ▶   Good interface for typehinting




                          © All rights reserved. Zend Technologies, Inc.
Service Locator
use ZendDiServiceLocator,
    ZendEventManagerEventManager;

class MyLocator extends ServiceLocator
{
    protected $events;
    protected $map = array('events' => 'getEvents');

    public function getEvents()
    {
        if (null !== $this->events) {
            return $this->events;
        }
        $this->events = new EventManager();
        return $this->events;
    }
}
                     © All rights reserved. Zend Technologies, Inc.
ZF2 Approach
●   Dependency Injection Container
    ▶   Scaffolding for constructor and setter injection
    ▶   Use programmatically, or from configuration
    ▶   Typically used to seed a service locator




                         © All rights reserved. Zend Technologies, Inc.
Dependency Injection
$db = new Definition('MyDbAdapterSqlite');
$db->setParam('name', __DIR__ .
'/../data/db/users.db');

$mapper = new Definition('MyMapperDb');
$mapper->addMethodCall(
    'setAdapter', array(new Reference('db')));

$service = new Definition('MyResourceUsers');
$service->setParam('mapper', new
Reference('mapper'));

$di = new DependencyInjector;
$di->setDefinitions(array(
    'db'     => $db,
    'mapper' => $mapper,
    'users' => $service,
));
                     © All rights reserved. Zend Technologies, Inc.
Controllers as services
●   Solves issue of controller dependencies
●   Each request only instantiates what's needed
    for that request
●   Better testability of controllers




                      © All rights reserved. Zend Technologies, Inc.
Controllers as services


$userController = new
Definition('SiteControllerUser');
$userController->setParam(
    'service', new Reference('users'));
$di->setDefinition($userController, 'controller-
user');

// Inside dispatcher:
$controller = $di->get($controllerName);
$result = $controller->dispatch($request, $response);




                     © All rights reserved. Zend Technologies, Inc.
More to come!




56    © All rights reserved. Zend Technologies, Inc.
Zend Framework 2.0
●   Schedule:
    ▶   MVC milestone by end of May
    ▶   Preview Release following MVC milestone
    ▶   Beta release during summer
    ▶   Stable by end-of-year




                        © All rights reserved. Zend Technologies, Inc.
Resources




58   © All rights reserved. Zend Technologies, Inc.
●   ZF2 Wiki: http://bit.ly/zf2wiki
●   ZF2 Git information: http://bit.ly/zf2gitguide
●   ZF2 MVC sandbox:
    git://git.mwop.net/zf2sandbox.git
●   ZF2 DI prototype: http://bit.ly/gBBnDS




                     © All rights reserved. Zend Technologies, Inc.
Thank you!
     ●   http://framework.zend.com/
     ●   http://twitter.com/weierophinney




60                        © All rights reserved. Zend Technologies, Inc.
Webinar
    To watch the webinar please go to:
    http://www.zend.com/en/webinar/Framework/
    70170000000bX3J-webinar-zf-2-patterns-
    20110330.flv
    Or
    http://bit.ly/qXeCWI

    (short registration required)




Insert->Header & Footer             © All rights reserved. Zend Technologies, Inc.   61

Weitere ähnliche Inhalte

Was ist angesagt?

Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormMichelangelo van Dam
 
Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11Stephan Hochdörfer
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Heiko Behrens
 
Interactive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and ArchitectureInteractive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and ArchitectureJavaDayUA
 
JShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java PlatformJShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java PlatformJavaDayUA
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)James Titcumb
 
How to build customizable multitenant web applications - PHPBNL11
How to build customizable multitenant web applications - PHPBNL11How to build customizable multitenant web applications - PHPBNL11
How to build customizable multitenant web applications - PHPBNL11Stephan Hochdörfer
 
Secure Programming
Secure ProgrammingSecure Programming
Secure Programmingalpha0
 
Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendKirill Chebunin
 
JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...
JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...
JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...Jorge Hidalgo
 
Apigility reloaded
Apigility reloadedApigility reloaded
Apigility reloadedRalf Eggert
 
Irving iOS Jumpstart Meetup - Objective-C Session 1b
Irving iOS Jumpstart Meetup - Objective-C Session 1bIrving iOS Jumpstart Meetup - Objective-C Session 1b
Irving iOS Jumpstart Meetup - Objective-C Session 1birving-ios-jumpstart
 
The Art of Metaprogramming in Java
The Art of Metaprogramming in Java  The Art of Metaprogramming in Java
The Art of Metaprogramming in Java Abdelmonaim Remani
 
Review unknown code with static analysis - bredaphp
Review unknown code with static analysis - bredaphpReview unknown code with static analysis - bredaphp
Review unknown code with static analysis - bredaphpDamien Seguy
 
Quick Intro To JRuby
Quick Intro To JRubyQuick Intro To JRuby
Quick Intro To JRubyFrederic Jean
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Guillaume Laforge
 
Invokedynamic / JSR-292
Invokedynamic / JSR-292Invokedynamic / JSR-292
Invokedynamic / JSR-292ytoshima
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 

Was ist angesagt? (20)

Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
Interactive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and ArchitectureInteractive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and Architecture
 
JShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java PlatformJShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java Platform
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
How to build customizable multitenant web applications - PHPBNL11
How to build customizable multitenant web applications - PHPBNL11How to build customizable multitenant web applications - PHPBNL11
How to build customizable multitenant web applications - PHPBNL11
 
Secure Programming
Secure ProgrammingSecure Programming
Secure Programming
 
Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friend
 
JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...
JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...
JavaOne 2014 - CON2013 - Code Generation in the Java Compiler: Annotation Pro...
 
Apigility reloaded
Apigility reloadedApigility reloaded
Apigility reloaded
 
Irving iOS Jumpstart Meetup - Objective-C Session 1b
Irving iOS Jumpstart Meetup - Objective-C Session 1bIrving iOS Jumpstart Meetup - Objective-C Session 1b
Irving iOS Jumpstart Meetup - Objective-C Session 1b
 
CFEngine 3
CFEngine 3CFEngine 3
CFEngine 3
 
The Art of Metaprogramming in Java
The Art of Metaprogramming in Java  The Art of Metaprogramming in Java
The Art of Metaprogramming in Java
 
Review unknown code with static analysis - bredaphp
Review unknown code with static analysis - bredaphpReview unknown code with static analysis - bredaphp
Review unknown code with static analysis - bredaphp
 
Quick Intro To JRuby
Quick Intro To JRubyQuick Intro To JRuby
Quick Intro To JRuby
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
Invokedynamic / JSR-292
Invokedynamic / JSR-292Invokedynamic / JSR-292
Invokedynamic / JSR-292
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 

Andere mochten auch

Informaciòn legal y jurìdica
Informaciòn legal y jurìdicaInformaciòn legal y jurìdica
Informaciòn legal y jurìdicajbyasoc
 
Sexuality - Final Poster
Sexuality - Final PosterSexuality - Final Poster
Sexuality - Final PosterAmanda Shea
 
Group 4 Contemp Project
Group 4 Contemp ProjectGroup 4 Contemp Project
Group 4 Contemp ProjectYunji Kim
 
El mono bondadoso
El mono bondadosoEl mono bondadoso
El mono bondadosoUPCI
 
IMPERIAL PALACE WATERPARK RESORT & SPA IN MACTAN
IMPERIAL PALACE WATERPARK RESORT & SPA IN MACTANIMPERIAL PALACE WATERPARK RESORT & SPA IN MACTAN
IMPERIAL PALACE WATERPARK RESORT & SPA IN MACTANDaisy Mendez
 
fatwa tentang orang awam syi'ah
fatwa tentang orang awam syi'ahfatwa tentang orang awam syi'ah
fatwa tentang orang awam syi'ahR&R Darulkautsar
 
Secrets Of Successful Property Managers
Secrets Of Successful Property ManagersSecrets Of Successful Property Managers
Secrets Of Successful Property ManagersSLT Properties, LLC
 
front page resume
front page resumefront page resume
front page resumeAlan Redcay
 
Certificate of Organizer
Certificate of OrganizerCertificate of Organizer
Certificate of Organizersumroze Rafeeq
 
PHP and database functionality
PHP and database functionalityPHP and database functionality
PHP and database functionalitySayed Ahmed
 
PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...
PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...
PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...Maria Luisa Gonzales
 
Intelligent Security, Compliance and Privacy in Office 365
Intelligent Security, Compliance and Privacy in Office 365Intelligent Security, Compliance and Privacy in Office 365
Intelligent Security, Compliance and Privacy in Office 365Miguel Isidoro
 

Andere mochten auch (17)

Nuevas Tecnologías
Nuevas TecnologíasNuevas Tecnologías
Nuevas Tecnologías
 
Recurso 4
Recurso 4Recurso 4
Recurso 4
 
SBResume1
SBResume1SBResume1
SBResume1
 
Informaciòn legal y jurìdica
Informaciòn legal y jurìdicaInformaciòn legal y jurìdica
Informaciòn legal y jurìdica
 
Sexuality - Final Poster
Sexuality - Final PosterSexuality - Final Poster
Sexuality - Final Poster
 
Group 4 Contemp Project
Group 4 Contemp ProjectGroup 4 Contemp Project
Group 4 Contemp Project
 
El mono bondadoso
El mono bondadosoEl mono bondadoso
El mono bondadoso
 
Calif 2°e 10 07 15 i
Calif 2°e 10 07 15 iCalif 2°e 10 07 15 i
Calif 2°e 10 07 15 i
 
IMPERIAL PALACE WATERPARK RESORT & SPA IN MACTAN
IMPERIAL PALACE WATERPARK RESORT & SPA IN MACTANIMPERIAL PALACE WATERPARK RESORT & SPA IN MACTAN
IMPERIAL PALACE WATERPARK RESORT & SPA IN MACTAN
 
fatwa tentang orang awam syi'ah
fatwa tentang orang awam syi'ahfatwa tentang orang awam syi'ah
fatwa tentang orang awam syi'ah
 
Secrets Of Successful Property Managers
Secrets Of Successful Property ManagersSecrets Of Successful Property Managers
Secrets Of Successful Property Managers
 
front page resume
front page resumefront page resume
front page resume
 
Certificate of Organizer
Certificate of OrganizerCertificate of Organizer
Certificate of Organizer
 
PHP and database functionality
PHP and database functionalityPHP and database functionality
PHP and database functionality
 
Reality Theory Case Study
Reality Theory Case StudyReality Theory Case Study
Reality Theory Case Study
 
PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...
PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...
PREPAREDNESS OF BICOL COLLEGE IN THE ACCREDITATION OF BSHM PROGRAM BY THE PAC...
 
Intelligent Security, Compliance and Privacy in Office 365
Intelligent Security, Compliance and Privacy in Office 365Intelligent Security, Compliance and Privacy in Office 365
Intelligent Security, Compliance and Privacy in Office 365
 

Ähnlich wie Zend Framework 2 Patterns

ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)
ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)
ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)ZFConf Conference
 
How to Manage Cloud Infrastructures using Zend Framework
How to Manage Cloud Infrastructures using Zend FrameworkHow to Manage Cloud Infrastructures using Zend Framework
How to Manage Cloud Infrastructures using Zend FrameworkZend by Rogue Wave Software
 
2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps2010 07-28-testing-zf-apps
2010 07-28-testing-zf-appsVenkata Ramana
 
Z ray plugins for dummies
Z ray plugins for dummiesZ ray plugins for dummies
Z ray plugins for dummiesDmitry Zbarski
 
PHP traits, treat or threat?
PHP traits, treat or threat?PHP traits, treat or threat?
PHP traits, treat or threat?Nick Belhomme
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)James Titcumb
 
Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...
Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...
Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...Zend by Rogue Wave Software
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)James Titcumb
 
Eclipse HandsOn Workshop
Eclipse HandsOn WorkshopEclipse HandsOn Workshop
Eclipse HandsOn WorkshopBastian Feder
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
 
Php7 extensions workshop
Php7 extensions workshopPhp7 extensions workshop
Php7 extensions workshopjulien pauli
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationJace Ju
 
Zend Framework 2 Components
Zend Framework 2 ComponentsZend Framework 2 Components
Zend Framework 2 ComponentsShawn Stratton
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)James Titcumb
 
Xdebug - Derick Rethans - Barcelona PHP Conference 2008
Xdebug - Derick Rethans - Barcelona PHP Conference 2008Xdebug - Derick Rethans - Barcelona PHP Conference 2008
Xdebug - Derick Rethans - Barcelona PHP Conference 2008phpbarcelona
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 

Ähnlich wie Zend Framework 2 Patterns (20)

ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)
ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)
ZFConf 2012: Zend Framework 2, a quick start (Enrico Zimuel)
 
How to Manage Cloud Infrastructures using Zend Framework
How to Manage Cloud Infrastructures using Zend FrameworkHow to Manage Cloud Infrastructures using Zend Framework
How to Manage Cloud Infrastructures using Zend Framework
 
2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps
 
Using PHP 5.3 Namespaces for Fame and Fortune
Using PHP 5.3 Namespaces for Fame and FortuneUsing PHP 5.3 Namespaces for Fame and Fortune
Using PHP 5.3 Namespaces for Fame and Fortune
 
Z ray plugins for dummies
Z ray plugins for dummiesZ ray plugins for dummies
Z ray plugins for dummies
 
Zf2 phpquebec
Zf2 phpquebecZf2 phpquebec
Zf2 phpquebec
 
PHP traits, treat or threat?
PHP traits, treat or threat?PHP traits, treat or threat?
PHP traits, treat or threat?
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...
Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...
Costruire un sito e-commerce in alta affidabilità con Magento e Zend Server C...
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Eclipse HandsOn Workshop
Eclipse HandsOn WorkshopEclipse HandsOn Workshop
Eclipse HandsOn Workshop
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Php7 extensions workshop
Php7 extensions workshopPhp7 extensions workshop
Php7 extensions workshop
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & Application
 
Zend Framework 2 Components
Zend Framework 2 ComponentsZend Framework 2 Components
Zend Framework 2 Components
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
 
Xdebug - Derick Rethans - Barcelona PHP Conference 2008
Xdebug - Derick Rethans - Barcelona PHP Conference 2008Xdebug - Derick Rethans - Barcelona PHP Conference 2008
Xdebug - Derick Rethans - Barcelona PHP Conference 2008
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Test your modules
Test your modulesTest your modules
Test your modules
 

Mehr von Zend by Rogue Wave Software

Building and managing applications fast for IBM i
Building and managing applications fast for IBM iBuilding and managing applications fast for IBM i
Building and managing applications fast for IBM iZend by Rogue Wave Software
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Zend by Rogue Wave Software
 
The Sodium crypto library of PHP 7.2 (PHP Day 2018)
The Sodium crypto library of PHP 7.2 (PHP Day 2018)The Sodium crypto library of PHP 7.2 (PHP Day 2018)
The Sodium crypto library of PHP 7.2 (PHP Day 2018)Zend by Rogue Wave Software
 
Develop web APIs in PHP using middleware with Expressive (Code Europe)
Develop web APIs in PHP using middleware with Expressive (Code Europe)Develop web APIs in PHP using middleware with Expressive (Code Europe)
Develop web APIs in PHP using middleware with Expressive (Code Europe)Zend by Rogue Wave Software
 

Mehr von Zend by Rogue Wave Software (20)

Develop microservices in php
Develop microservices in phpDevelop microservices in php
Develop microservices in php
 
Speed and security for your PHP application
Speed and security for your PHP applicationSpeed and security for your PHP application
Speed and security for your PHP application
 
Building and managing applications fast for IBM i
Building and managing applications fast for IBM iBuilding and managing applications fast for IBM i
Building and managing applications fast for IBM i
 
Building web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend ExpressiveBuilding web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend Expressive
 
To PHP 7 and beyond
To PHP 7 and beyondTo PHP 7 and beyond
To PHP 7 and beyond
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
 
The Sodium crypto library of PHP 7.2 (PHP Day 2018)
The Sodium crypto library of PHP 7.2 (PHP Day 2018)The Sodium crypto library of PHP 7.2 (PHP Day 2018)
The Sodium crypto library of PHP 7.2 (PHP Day 2018)
 
Develop web APIs in PHP using middleware with Expressive (Code Europe)
Develop web APIs in PHP using middleware with Expressive (Code Europe)Develop web APIs in PHP using middleware with Expressive (Code Europe)
Develop web APIs in PHP using middleware with Expressive (Code Europe)
 
Middleware web APIs in PHP 7.x
Middleware web APIs in PHP 7.xMiddleware web APIs in PHP 7.x
Middleware web APIs in PHP 7.x
 
Ongoing management of your PHP 7 application
Ongoing management of your PHP 7 applicationOngoing management of your PHP 7 application
Ongoing management of your PHP 7 application
 
Developing web APIs using middleware in PHP 7
Developing web APIs using middleware in PHP 7Developing web APIs using middleware in PHP 7
Developing web APIs using middleware in PHP 7
 
The Docker development template for PHP
The Docker development template for PHPThe Docker development template for PHP
The Docker development template for PHP
 
The most exciting features of PHP 7.1
The most exciting features of PHP 7.1The most exciting features of PHP 7.1
The most exciting features of PHP 7.1
 
Unit testing for project managers
Unit testing for project managersUnit testing for project managers
Unit testing for project managers
 
The new features of PHP 7
The new features of PHP 7The new features of PHP 7
The new features of PHP 7
 
Deploying PHP apps on the cloud
Deploying PHP apps on the cloudDeploying PHP apps on the cloud
Deploying PHP apps on the cloud
 
Data is dead. Long live data!
Data is dead. Long live data! Data is dead. Long live data!
Data is dead. Long live data!
 
Optimizing performance
Optimizing performanceOptimizing performance
Optimizing performance
 
Resolving problems & high availability
Resolving problems & high availabilityResolving problems & high availability
Resolving problems & high availability
 
Developing apps faster
Developing apps fasterDeveloping apps faster
Developing apps faster
 

Kürzlich hochgeladen

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 

Kürzlich hochgeladen (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

Zend Framework 2 Patterns

  • 1. Zend Framework 2 Patterns Matthew Weier O'Phinney Project Lead, Zend Framework To watch the webinar please go to: http://www.zend.com/en/webinar/Framework/70170000000bX3J- webinar-zf-2-patterns-20110330.flv © All rights reserved. Zend Technologies, Inc.
  • 2. Roadmap for today ● Namespaces and Autoloading ● Exceptions ● Configuration ● Plugin systems ● Dispatching ● Inversion of Control © All rights reserved. Zend Technologies, Inc.
  • 3. Format ● List The Problems ● Detail the ZF2 Approach © All rights reserved. Zend Technologies, Inc.
  • 4. But first, some history © All rights reserved. Zend Technologies, Inc.
  • 5. Zend Framework 1.X ● 1.0 Released in July 2007 ● Largely evolutionary development ▶ Inconsistencies in APIs, particularly surrounding plugins and configuration ▶ Best practices have been discovered over time ▶ Many key features for modern applications have been added in recent versions © All rights reserved. Zend Technologies, Inc.
  • 6. Zend Framework 2.0 ● First new major release ▶ Allowing us to break backwards compatibility ● Focus is on: ▶ Consistency ▶ Performance ▶ Documentation ▶ User productivity © All rights reserved. Zend Technologies, Inc.
  • 7. Namespaces and Autoloading 7 © All rights reserved. Zend Technologies, Inc.
  • 8. The Problems ● Lengthy class names ▶ Difficult to refactor ▶ Difficult to retain semantics with shorter names ● Performance issues ▶ Many classes are used JIT, and shouldn't be loaded until needed ● Missing require_once statements lead to errors © All rights reserved. Zend Technologies, Inc.
  • 9. ZF2 Approach: Namespaces ● Formalize the prefixes used in ZF1 ▶ Namespace separator correlates to directory separator ● Help identify dependencies (imports) ▶ Allows refactoring using different implementations easier ▶ Makes packaging easier © All rights reserved. Zend Technologies, Inc.
  • 10. Namespaces namespace ZendEventManager; use ZendStdlibCallbackHandler; class EventManager implements EventCollection { /* ... */ } © All rights reserved. Zend Technologies, Inc.
  • 11. Namespaces ● Interfaces as namespaces ▶ Interface names are adjectives or nouns ▶ Concrete implementations in a sub-namespace named after the interface ▶ Contract-Oriented paradigm © All rights reserved. Zend Technologies, Inc.
  • 12. Interfaces as Namespaces Zend/Session namespace ZendSession; |-- Storage.php interface Storage `-- Storage { |-- /* ... */ ArrayStorage.php } `-- SessionStorage.php namespace ZendSessionStorage; use ArrayObject, ZendSessionStorage, ZendSessionException; class ArrayStorage extends ArrayObject implements Storage { /* ... */ } © All rights reserved. Zend Technologies, Inc.
  • 13. ZF2 Approach: Autoloading ● No more require_once calls! ● Multiple approaches ▶ ZF1-style include_path autoloader ▶ Per-namespace/prefix autoloading ▶ Class-map autoloading © All rights reserved. Zend Technologies, Inc.
  • 14. ZF1-Style Autoloading require_once 'Zend/Loader/StandardAutoloader.php'; $loader = new ZendLoaderStandardAutoloader(array( 'fallback_autoloader' => true, )); $loader->register(); © All rights reserved. Zend Technologies, Inc.
  • 15. ZF2 NS/Prefix Autoloading require_once 'Zend/Loader/StandardAutoloader.php'; $loader = new ZendLoaderStandardAutoloader(); $loader->registerNamespace( 'My', __DIR__ . '/../library/My') ->registerPrefix( 'Phly_', __DIR__ . '/../library/Phly'); $loader->register(); © All rights reserved. Zend Technologies, Inc.
  • 16. ZF2 Class-Map Autoloading return array( 'MyFooBar' => __DIR__ . '/Foo/Bar.php', ); require_once 'Zend/Loader/ClassMapAutoloader.php'; $loader = new ZendLoaderClassMapAutoloader(); $loader->registerAutoloadMap( __DIR__ . '/../library/.classmap.php'); $loader->register(); © All rights reserved. Zend Technologies, Inc.
  • 17. Exceptions 17 © All rights reserved. Zend Technologies, Inc.
  • 18. The Problems ● All exceptions derived from a common class ● No ability to extend more semantic exception types offered in SPL © All rights reserved. Zend Technologies, Inc.
  • 19. ZF2 Approach ● Eliminated Zend_Exception ● Each component defines a marker Exception interface ● Additional exception types are created in an Exception subnamespace ▶ These extend SPL exceptions, and implement the component-level exception interface © All rights reserved. Zend Technologies, Inc.
  • 20. What the solution provides ● Catch specific exception types ● Catch SPL exception types ● Catch any component-level exception ● Catch based on global exception type © All rights reserved. Zend Technologies, Inc.
  • 21. Exceptions in use Zend/EventManager namespace |-- Exception.php ZendEventManager; `-- Exception `-- InvalidArgument- interface Exception {} Exception.php namespace ZendEventManagerException; use ZendEventManagerException; class InvalidArgumentException extends InvalidArgumentException implements Exception {} © All rights reserved. Zend Technologies, Inc.
  • 22. Exceptions in use namespace ZendEventManagerException; use ZendEventManagerException; try { $events->trigger('foo.bar', $object); } catch (InvalidArgumentException $e) { } catch (Exception $e) { } catch (InvalidArgumentException $e) { } catch (Exception $e) { } © All rights reserved. Zend Technologies, Inc.
  • 23. Configuration 23 © All rights reserved. Zend Technologies, Inc.
  • 24. The Problems ● Case-SeNSItiviTy ● Varying APIs ▶ setOptions() ▶ setConfig() ▶ __construct() ▶ explicit setters © All rights reserved. Zend Technologies, Inc.
  • 25. ZF2 Approach ● Option names will be lowercase_underscore_separated_word s ● Standard solution across components ▶ setOptions() style, proxying to setters, or ▶ per-component configuration objects © All rights reserved. Zend Technologies, Inc.
  • 26. setOptions() style class Foo { public function setOptions($options) { if (!is_array($options) && !($options instanceof Traversable) ) { throw new InvalidArgumentException(); } foreach ($options as $key => $value) { $method = normalize($key); if (method_exists($this, $method)) { $this->$method($value); } } © All rights reserved. Zend Technologies, Inc.
  • 27. Options object style class FooOptions extends Options { public $bar; public $baz; public function __construct($options = null) { if (!is_array($options) && !($options instanceof Traversable) ) { throw new InvalidArgumentException(); } foreach ($options as $key => $value) { $prop = normalize($key); $this->$prop = $value; } } } © All rights reserved. Zend Technologies, Inc.
  • 28. Options object style class Foo { public function __construct(Options $options = null) { if (null !== $options) { foreach ($options as $key => $value) { $this->$key = $value; } } } } © All rights reserved. Zend Technologies, Inc.
  • 29. Plugin Architectures 29 © All rights reserved. Zend Technologies, Inc.
  • 30. Terminology ● For our purposes, a “plugin” is any class that is determined at runtime. ▶ Action and view helpers ▶ Adapters ▶ Filters and validators © All rights reserved. Zend Technologies, Inc.
  • 31. The Problems ● Varying approaches to dynamically discovering plugin classes ▶ Prefix-path stacks (most common) ▶ Paths relative to the calling class ▶ Setters to indicate classes ● Most common approach is terrible ▶ Bad performance ▶ Hard to debug ▶ No caching of discovered plugins © All rights reserved. Zend Technologies, Inc.
  • 32. ZF2 Approach: Plugin Broker ● Separate Plugin Location interface ▶ Allows varying implementation of plugin lookup ● Separate Plugin Broker interface ▶ Composes a Plugin Locator © All rights reserved. Zend Technologies, Inc.
  • 33. ZF2 Approach: Plugin Broker ● Standard implementation across components ▶ Subclassing standard implementation allows type- hinting, caching discovered plugins, etc. ▶ while allowing you to substitute your own implementations ● Class-map location by default ● 2-5x performance gains! ● Easier to debug © All rights reserved. Zend Technologies, Inc.
  • 34. Plugin class location namespace ZendLoader; interface ShortNameLocater { public function isLoaded($name); public function getClassName($name); public function load($name); } namespace ZendView; use ZendLoaderPluginClassLoader; class HelperLoader extends PluginClassLoader { protected $plugins = array( 'action' => 'ZendViewHelperAction', 'baseurl' => 'ZendViewHelperBaseUrl', /* ... */ ); } © All rights reserved. Zend Technologies, Inc.
  • 35. Plugin broker namespace ZendLoader; interface Broker { public function load($plugin, array $options = null); public function getPlugins(); public function isLoaded($name); public function register($name, $plugin); public function unregister($name); public function setClassLoader( ShortNameLocater $loader); public function getClassLoader(); } © All rights reserved. Zend Technologies, Inc.
  • 36. Plugin broker class HelperBroker extends PluginBroker { protected $defaultClassLoader = 'ZendViewHelperLoader'; protected $view; public function setView(Renderer $view) {} public function getView() {} public function load($plugin, array $options = null) { $helper = parent::load($plugin, $options); if (null !== ($view = $this->getView())) { $helper->setView($view); } return $helper; } protected function validatePlugin($plugin) { if (!$plugin instanceof Helper) { throw new InvalidHelperException(); } return true; } } © All rights reserved. Zend Technologies, Inc.
  • 37. ZF2 Approach: Events ● Trigger events at interesting points in your application ▶ Use as basic subject/observer pattern ▶ Or as intercepting filters ▶ Or a full-fledged Aspect-Oriented Programming system © All rights reserved. Zend Technologies, Inc.
  • 38. ZF2 Approach: Events ● Compose an EventManager to a class ● Attach handlers to events ▶ Handlers receive an Event ● event name ● target (calling) object ● parameters passed ▶ Handlers can also be attached statically © All rights reserved. Zend Technologies, Inc.
  • 39. Triggering an event public function doSomething( $with, $params = array() ) { $this->events()->trigger( __FUNCTION__, compact('with', 'params') ); /* ... */ } © All rights reserved. Zend Technologies, Inc.
  • 40. Listening to an event use ZendEventManagerEventManager as Events; $events = new Events(); $events->attach('doSomething', function($e) use ($log) { $event = $e->getName(); $target = get_class($e->getTarget()); $params = json_encode($e->getParams()); $message = sprintf('%s (%s): %s', $event, $target, $params); $log->info($message); }); © All rights reserved. Zend Technologies, Inc.
  • 41. Attaching statically to an event use ZendEventManagerStaticEventManager as AllEvents; $events = AllEvents::getInstance(); // Specify the class composing an EventManager // as first arg $events->attach('Foo', 'doSomething', function($e) {}); © All rights reserved. Zend Technologies, Inc.
  • 42. Dispatchers 42 © All rights reserved. Zend Technologies, Inc.
  • 43. The Problems ● Not terribly performant ● Hard to customize ● Hard to inject controllers with dependencies ● Forces pre-initialization of resources if you want them configured by Zend_Application © All rights reserved. Zend Technologies, Inc.
  • 44. ZF2 Approach ● Discrete Request, Response, and Dispatchable interfaces ▶ Request encompasses request environment ▶ Response aggregates response returned ▶ Dispatchable objects formalize a Strategy pattern © All rights reserved. Zend Technologies, Inc.
  • 45. ZF2 Approach ● Anything Dispatchable can be attached to the MVC ▶ Server components (XML-RPC, JSON-RPC, etc.) ● Allows building your own MVC approach ▶ Do you want action methods to receive explicit arguments? ▶ Do you want to select a different action method based on request headers? © All rights reserved. Zend Technologies, Inc.
  • 46. MVC Interfaces interface Message { public function setMetadata($spec, $value = null); public function getMetadata($key = null); public function setContent($content); public function getContent(); } interface Request interface Response extends Message extends Message { { public function public function __toString(); __toString(); public function public function fromString($string); fromString($string); } public function send(); } © All rights reserved. Zend Technologies, Inc.
  • 47. MVC Interfaces interface Dispatchable { public function dispatch( Request $request, Response $response = null); } © All rights reserved. Zend Technologies, Inc.
  • 48. Inversion of Control 48 © All rights reserved. Zend Technologies, Inc.
  • 49. The Problems ● How do objects get dependencies? ▶ In particular, how do Controllers get dependencies? © All rights reserved. Zend Technologies, Inc.
  • 50. ZF2 Approach ● Service Locator ▶ Basic pattern: ● set($name, $service) ● get($name) ▶ Formalization of application services (mailer, logger, profiler, etc.) ▶ Good interface for typehinting © All rights reserved. Zend Technologies, Inc.
  • 51. Service Locator use ZendDiServiceLocator, ZendEventManagerEventManager; class MyLocator extends ServiceLocator { protected $events; protected $map = array('events' => 'getEvents'); public function getEvents() { if (null !== $this->events) { return $this->events; } $this->events = new EventManager(); return $this->events; } } © All rights reserved. Zend Technologies, Inc.
  • 52. ZF2 Approach ● Dependency Injection Container ▶ Scaffolding for constructor and setter injection ▶ Use programmatically, or from configuration ▶ Typically used to seed a service locator © All rights reserved. Zend Technologies, Inc.
  • 53. Dependency Injection $db = new Definition('MyDbAdapterSqlite'); $db->setParam('name', __DIR__ . '/../data/db/users.db'); $mapper = new Definition('MyMapperDb'); $mapper->addMethodCall( 'setAdapter', array(new Reference('db'))); $service = new Definition('MyResourceUsers'); $service->setParam('mapper', new Reference('mapper')); $di = new DependencyInjector; $di->setDefinitions(array( 'db' => $db, 'mapper' => $mapper, 'users' => $service, )); © All rights reserved. Zend Technologies, Inc.
  • 54. Controllers as services ● Solves issue of controller dependencies ● Each request only instantiates what's needed for that request ● Better testability of controllers © All rights reserved. Zend Technologies, Inc.
  • 55. Controllers as services $userController = new Definition('SiteControllerUser'); $userController->setParam( 'service', new Reference('users')); $di->setDefinition($userController, 'controller- user'); // Inside dispatcher: $controller = $di->get($controllerName); $result = $controller->dispatch($request, $response); © All rights reserved. Zend Technologies, Inc.
  • 56. More to come! 56 © All rights reserved. Zend Technologies, Inc.
  • 57. Zend Framework 2.0 ● Schedule: ▶ MVC milestone by end of May ▶ Preview Release following MVC milestone ▶ Beta release during summer ▶ Stable by end-of-year © All rights reserved. Zend Technologies, Inc.
  • 58. Resources 58 © All rights reserved. Zend Technologies, Inc.
  • 59. ZF2 Wiki: http://bit.ly/zf2wiki ● ZF2 Git information: http://bit.ly/zf2gitguide ● ZF2 MVC sandbox: git://git.mwop.net/zf2sandbox.git ● ZF2 DI prototype: http://bit.ly/gBBnDS © All rights reserved. Zend Technologies, Inc.
  • 60. Thank you! ● http://framework.zend.com/ ● http://twitter.com/weierophinney 60 © All rights reserved. Zend Technologies, Inc.
  • 61. Webinar To watch the webinar please go to: http://www.zend.com/en/webinar/Framework/ 70170000000bX3J-webinar-zf-2-patterns- 20110330.flv Or http://bit.ly/qXeCWI (short registration required) Insert->Header & Footer © All rights reserved. Zend Technologies, Inc. 61