10 Years of Zend Framework

Original Architecture

  • Components
  • Bound together by an MVC

Evolution of v1

  • Forms
  • Layouts
  • Zend_Application
  • Dojo, jQuery integration

Revolution: ZF2

  • Event-driven architecture
  • Dependency injection
  • First class modules

… at a cost

  • Complete break in compatibility.
  • Targeting expert developers == less inviting
  • Components depend on integration provided by MVC layer

Ecosystem changes

Composer

FIG

Framework Interop Group

PSR-7

Every framework abstracts HTTP differently.

Let's standardize that.

Frameworks must change

The job of a framework is to provide plumbing, and get out of your way.

ZF3 Goals

  • Componentization and re-use
  • Performance
  • Usability
  • Focus on PSR-7 and middleware

What we've accomplished

Components

All components are now versioned separately.

(Full story at bit.ly/zf2-split)

Standardized Package Structure

  • PSR-4 structure for source and tests.
  • Documentation per package
    (in progress)
  • Standard QA toolchain; per-package continuous integration.

ZF2 Package

The zendframework package now simply depends on components.


{
  "require": {
    "zendframework/zend-authentication": "^2.5",
    "zendframework/zend-cache": "^2.5",
    "zendframework/zend-captcha": "^2.5",
    "etc": "*"
  }
}
          

Back to Basics

ZF3 will reduce dependencies
to only what's needed for the MVC.

Use Composer to add what you need.

Change is inevitable

Service Manager

  • container-interop
  • Consistent interfaces.
  • Re-use factories for multiple named services.
  • Immutable.
  • Performant (4X faster)!
  • Mostly backwards compatible!

New method: build


public function build($name, array $options = null)
        

For when you need a factory; think plugins

FactoryInterface


public function __invoke(
    ContainerInterface $container,
    $requestedName,
    array $options = null
)
        

Forward Compatibility

Write your current factories as invokables.


public function __invoke(
    ContainerInterface $container
)
        

EventManager

  • 4X–15x performance based on use case!
  • BC breaks:
    • Removed argument overloading for trigger().
    • Aggregate attachment is moved to aggregate implementations.

Triggers


trigger($eventName, $target = null, $argv = []);
triggerUntil(callable $callback, $eventName, $target = null, $argv = []);
triggerEvent(EventInterface $event);
triggerEventUntil(callable $callback, EventInterface $event);
        

Aggregates

Before:


$events->attach($aggregate);
$events->attachAggregate($aggregate);
$aggregate->attach($events);
        

After:


$aggregate->attach($events);
          

MVC

  • Updated to changes in zend-servicemanager.
  • Updated to changes in zend-eventmanager.
  • Essentially stays the same.
  • But adds a MiddlewareListener.

Routing to Middleware


'oauth' => [
    'type' => 'Literal',
    'options' => [
        'route' => '/oauth',
        'defaults' => [
            'middleware' => OAuthMiddleware::class,
        ],
    ],
],
        

MVC Availability

4–6 weeks!

Enough with the boring stuff

Time to Reflect

Where is the PHP community headed?

Composer

FIG

Creating shared interfaces.

Users can target abstractions, not implementations.

PSR-7

HTTP Message Interfaces

Providing a common HTTP abstraction to program against.

Middleware

Middleware

Middleware Signatures


function (ServerRequestInterface $request) : ResponseInterface

function (
    ServerRequestInterface $request,
    ResponseInterface $response
) : ResponseInterface

function (
    ServerRequestInterface $request,
    ResponseInterface $response,
    callable $next
) : ResponseInterface
        

container-interop


interface ContainerInterface
{
    public function has($serviceName);
    public function get($serviceName);
}
        

Takeaways

Frameworks should be an implementation detail

Frameworks should be a commodity

Frameworks should get out of the way of your code

Expressive

PSR-7 middleware microframework

  • Provides and consumes a routing interface.
  • Pulls matched middleware from a ContainerInterface.
  • Provides a templating interface, if you need it.
  • Provides error handling, and a way to hook into it.

In action:

Expresive installer

Expressive

Wiring together commodity components.

Own your codebase

ZF3 is a Movement

An end to framework silos.

Thank you!

Matthew Weier O'Phinney

http//framework.zend.com
https://apigility.org
https://mwop.net @mwop

Rate this talk: https://joind.in/15622