building websites with zend expressive 3 · 2018-02-13 · building websites with zend expressive 3...

87
Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Upload: others

Post on 25-May-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Building Websiteswith Zend Expressive 3

Rob Allen, Nineteen Feet  

February 2018 ~ @akrabat

Page 2: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

A microframework with fullstack components

Rob Allen ~ @akrabat

What is Zend Expressive?
Page 3: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

µFramework core• Router• Container• Template renderer• Error handler• Configuration

Rob Allen ~ @akrabat

Page 4: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Ecosystem• Filtering and validation• API rendering: HAL & Problem-API• Database abstraction• Session handling• Logging• Mail• Pagination• Caching

Rob Allen ~ @akrabat

Page 5: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

AgnosticRouter:

FastRoute, Aura.Router or Zend RouterDI Container:

Aura.Di, Auryn, Pimple, Symfony DI Container orZend-ServiceManager

Template:Plates, Twig or Zend View

Rob Allen ~ @akrabat

Page 6: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Middleware pipeline 

Rob Allen ~ @akrabat

Page 7: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;

use Psr\Http\Message\ResponseInterface;

use Psr\Http\Message\ServerRequestInterface;

interface MiddlewareInterface

{

public function process(

ServerRequestInterface $request,

RequestHandlerInterface $handler

) : ResponseInterface;

}

Rob Allen ~ @akrabat

Page 8: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;

use Psr\Http\Message\ResponseInterface;

use Psr\Http\Message\ServerRequestInterface;

interface MiddlewareInterface

{

public function process(

ServerRequestInterface $request,

RequestHandlerInterface $handler

) : ResponseInterface;

}

Rob Allen ~ @akrabat

Page 9: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;

use Psr\Http\Message\ResponseInterface;

use Psr\Http\Message\ServerRequestInterface;

interface MiddlewareInterface

{

public function process(

ServerRequestInterface $request,

RequestHandlerInterface $handler

) : ResponseInterface;

}

Rob Allen ~ @akrabat

Page 10: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;

use Psr\Http\Message\ResponseInterface;

use Psr\Http\Message\ServerRequestInterface;

interface MiddlewareInterface

{

public function process(

ServerRequestInterface $request,

RequestHandlerInterface $handler

) : ResponseInterface;

}

Rob Allen ~ @akrabat

Page 11: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Structure of middlewareclass TimerMiddleware implements MiddlewareInterface

{

public function process($request, $handler)

{

$start = microtime(true);

$response = $handler->handle($request);

$taken = microtime(true) - $start;

$response->getBody()->write("<!-- Time: $taken -->");

return $response;

}

}

Rob Allen ~ @akrabat

Page 12: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Structure of middlewareclass TimerMiddleware implements MiddlewareInterface

{

public function process($request, $handler)

{

$start = microtime(true);

$response = $handler->handle($request);

$taken = microtime(true) - $start;

$response->getBody()->write("<!-- Time: $taken -->");

return $response;

}

}

Rob Allen ~ @akrabat

Page 13: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Structure of middlewareclass TimerMiddleware implements MiddlewareInterface

{

public function process($request, $handler)

{

$start = microtime(true);

$response = $handler->handle($request);

$taken = microtime(true) - $start;

$response->getBody()->write("<!-- Time: $taken -->");

return $response;

}

}

Rob Allen ~ @akrabat

Page 14: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Structure of middlewareclass TimerMiddleware implements MiddlewareInterface

{

public function process($request, $handler)

{

$start = microtime(true);

$response = $handler->handle($request);

$taken = microtime(true) - $start;

$response->getBody()->write("<!-- Time: $taken -->");

return $response;

}

}

Rob Allen ~ @akrabat

Page 15: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Structure of middlewareclass TimerMiddleware implements MiddlewareInterface

{

public function process($request, $handler)

{

$start = microtime(true);

$response = $handler->handle($request);

$taken = microtime(true) - $start;

$response->getBody()->write("<!-- Time: $taken -->");

return $response;

}

}

Rob Allen ~ @akrabat

Page 16: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Getting started

Rob Allen ~ @akrabat

Page 17: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Skeleton$ composer create-project zendframework/zend-expressive-skeleton new-app

Rob Allen ~ @akrabat

Creates a 'Simple, complete Expressive application'
Page 18: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Skeleton$ composer create-project zendframework/zend-expressive-skeleton new-app

Rob Allen ~ @akrabat

Creates a 'Simple, complete Expressive application'
Page 19: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Skeleton

Rob Allen ~ @akrabat

Page 20: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Directory structure.

├── bin/ ├── data/

├── config/ ├── public/

│   ├── autoload/ │   ├── css/

│   │   ├── dependencies.global.php │   ├── js/

│   │   ├── development.local.php │   └── index.php

│   │   ├── development.local.php.dist ├── src/

│   │   ├── local.php.dist │   └── App/

│   │   ├── router.global.php ├── test/

│   │   ├── templates.global.php │   └── AppTest/

│   │   └── zend-expressive.global.php ├── vendor/

│   ├── config.php ├── composer.json

│   ├── container.php ├── composer.lock

│   ├── development.config.php ├── phpcs.xml.dist

│   ├── development.config.php.dist └── phpunit.xml.dist

│   ├── pipeline.php

│   └── routes.php

Rob Allen ~ @akrabat

Page 21: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

src/App directory• Each module lives in its own namespace• Contains all code for application• ConfigProvider class for initialisation

• Configuration• DI registration

Rob Allen ~ @akrabat

Page 22: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

src/App directory structure└── src/

   └── App/

   ├── src/

   │   ├── Handler/

   │   │   ├── HomePageFactory.php

   │   │   ├── HomePageHandler.php

   │   │   └── PingHandler.php

   │   └── ConfigProvider.php

   ├── templates/

   │ ├── app/

   │ │   └── home-page.html.twig

   │ ├── error/

   │ │   ├── 404.html.twig

   │ │   └── error.html.twig

   │ └── layout/

   │ └── default.html.twig

└── test/

   └── AppTest/

   └── Handler/

Rob Allen ~ @akrabat

Page 23: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

A handler (AKA: an action)namespace App\Handler;

use ...;

class HomePageHandler implements RequestHandlerInterface

{

public function handle(

ServerRequestInterface $request

) : ResponseInterface {

return new HtmlResponse('<p>Hello World</p>');

}

}

Rob Allen ~ @akrabat

Page 24: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Let's write a web page!

Rob Allen ~ @akrabat

Page 25: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Bitcoin conversion 

Create a page that displays the current value of1 Bitcoin in £, $ & €

Rob Allen ~ @akrabat

Page 26: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Create a routeconfig/routes.php:

$app->get(

'/bitcoin',

App\Handler\BitcoinPageHandler::class,

'bitcoin'

);

Rob Allen ~ @akrabat

Let's break this down
Page 27: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Routes have a methodconfig/routes.php:

$app->get(

'/bitcoin',

App\Handler\BitcoinPageHandler::class,

'bitcoin'

);

Rob Allen ~ @akrabat

Page 28: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

HTTP Method$app->get()

$app->post()

$app->put()

$app->patch()

$app->delete()

Multiple methods:$app->any()

$app->route(…, …, ['GET', 'POST'], …);

Rob Allen ~ @akrabat

Page 29: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Routes have a patternconfig/routes.php:

$app->get(

'/bitcoin',

App\Handler\BitcoinPageHandler::class,

'bitcoin'

);

Rob Allen ~ @akrabat

Page 30: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

FastRoute URI pattern• Literal string match

$app->get('/hello', …);

Rob Allen ~ @akrabat

Page 31: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

FastRoute URI pattern• Literal string match

$app->get('/hello', …);

• Placeholders are wrapped in { }$app->get('/hello/{name}', …);

Rob Allen ~ @akrabat

Page 32: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

FastRoute URI pattern• Literal string match

$app->get('/hello', …);

• Placeholders are wrapped in { }$app->get('/hello/{name}', …);

• Optional segments are wrapped with [ ]$app->get('/news[/{year}[/{month}]]', …);

Rob Allen ~ @akrabat

Page 33: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

FastRoute URI pattern• Literal string match

$app->get('/hello', …);

• Placeholders are wrapped in { }$app->get('/hello/{name}', …);

• Optional segments are wrapped with [ ]$app->get('/news[/{year}[/{month}]]', …);

• Constrain placeholders via Regex$app->get('/news/{year:\d{4}}}', …); // exactly 4 digits

Rob Allen ~ @akrabat

Page 34: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Routes have a nameconfig/routes.php:

$app->get(

'/bitcoin',

App\Handler\BitcoinPageHandler::class,

'bitcoin'

);

Rob Allen ~ @akrabat

Page 35: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Url helper• Builds URLs from route names• Can be helpful to use . to group related route names

Use the router: $router->generateUri('user.profile', ['name' => 'Rob']);

or in the template: {{ path('user.profile', {'name': 'Rob'}) }}

Rob Allen ~ @akrabat

creates: /user/Rob
Page 36: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Routes have a handlerconfig/routes.php:

$app->get(

'/bitcoin',

App\Handler\BitcoinPageHandler::class,

'bitcoin'

);

Rob Allen ~ @akrabat

Page 37: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Handlers• Receive a PSR-7 Request• Manage business logic operations• Must return a PSR-7 Response• Implemented as PSR-15 RequestHandler• Create using CLI tool:

$ composer expressive handler:create \

App\\Handler\\BitcoinPageHandler

Rob Allen ~ @akrabat

Page 38: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Bitcoin handlerclass BitcoinPageHandler implements RequestHandlerInterface

{

public function handle(

ServerRequestInterface $request

) : ResponseInterface {

$data['prices'] = $this->btcService->getCurrentPrices();

return new HtmlResponse(

$this->template->render('app::bitcoin-page', $data)

);

}

Rob Allen ~ @akrabat

Page 39: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Bitcoin handlerclass BitcoinPageHandler implements RequestHandlerInterface

{

public function handle(

ServerRequestInterface $request

) : ResponseInterface {

$data['prices'] = $this->btcService->getCurrentPrices();

return new HtmlResponse(

$this->template->render('app::bitcoin-page', $data)

);

}

Rob Allen ~ @akrabat

Page 40: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Bitcoin handlerclass BitcoinPageHandler implements RequestHandlerInterface

{

public function handle(

ServerRequestInterface $request

) : ResponseInterface {

$data['prices'] = $this->btcService->getCurrentPrices();

return new HtmlResponse(

$this->template->render('app::bitcoin-page', $data)

);

}

Rob Allen ~ @akrabat

Page 41: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Bitcoin handlerclass BitcoinPageHandler implements RequestHandlerInterface

{

public function handle(

ServerRequestInterface $request

) : ResponseInterface {

$data['prices'] = $this->btcService->getCurrentPrices();

return new HtmlResponse(

$this->template->render('app::bitcoin-page', $data)

);

}

Rob Allen ~ @akrabat

Page 42: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Injecting dependenciesclass BitcoinPageHandler implements RequestHandlerInterface

{

protected $template;

protected $btcService;

public function __construct(

TemplateRendererInterface $template,

BitcoinService $btcService

) {

$this->template = $template;

$this->btcService = $btcService;

}

// …

Rob Allen ~ @akrabat

Page 43: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Expressive configurationA mushed-up associative array created from:

• Invoked ConfigProvider classes from libs and modules• Config files in config/autoload/

Common top level keys:

• dependencies • templates

• twig • filters

• validators • db

• cache

Rob Allen ~ @akrabat

Page 44: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

ConfigProvidernamespace App;

class ConfigProvider

{

public function __invoke() : array

{

return [

'dependencies' => $this->getDependencies(),

'templates' => $this->getTemplates(),

];

}

Rob Allen ~ @akrabat

Page 45: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

ConfigProvidernamespace App;

class ConfigProvider

{

public function __invoke() : array

{

return [

'dependencies' => $this->getDependencies(),

'templates' => $this->getTemplates(),

];

}

Rob Allen ~ @akrabat

Page 46: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Dependency configuration public function getDependencies() : array

{

return [

'factories' => [

Handler\BitcoinPageHandler::class =>

Handler\BitcoinPageFactory::class,

],

];

}

Rob Allen ~ @akrabat

Page 47: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Dependency configuration public function getDependencies() : array

{

return [

'factories' => [

Handler\BitcoinPageHandler::class =>

Handler\BitcoinPageFactory::class,

],

];

}

Rob Allen ~ @akrabat

Page 48: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Dependency configuration public function getDependencies() : array

{

return [

'factories' => [

Handler\BitcoinPageHandler::class =>

Handler\BitcoinPageFactory::class,

],

];

}

Rob Allen ~ @akrabat

Page 49: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Handler factoryReturn an instance of the handler with its injected dependencies

class BitcoinPageFactory

{

public function __invoke($container)

{

return new BitcoinPageHandler(

$container->get(TemplateRendererInterface::class),

$container->get(BitcoinService::class)

);

}

}

Rob Allen ~ @akrabat

Page 50: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Handler factoryReturn an instance of the handler with its injected dependencies

class BitcoinPageFactory

{

public function __invoke($container)

{

return new BitcoinPageHandler(

$container->get(TemplateRendererInterface::class),

$container->get(BitcoinService::class)

);

}

}

Rob Allen ~ @akrabat

Page 51: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Handler factoryReturn an instance of the handler with its injected dependencies

class BitcoinPageFactory

{

public function __invoke($container)

{

return new BitcoinPageHandler(

$container->get(TemplateRendererInterface::class),

$container->get(BitcoinService::class)

);

}

}

Rob Allen ~ @akrabat

Page 52: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

TemplatesExpressive's view layer

Rob Allen ~ @akrabat

Page 53: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Templating• Render method to convert page:$html = $this->template->render('app::bitcoin-page', $data);

• Templates are namespaced: namespace::template• Extension is resolved by the adapter:app::bitcoin-page => app/bitcoin-page.html.twig

Rob Allen ~ @akrabat

Page 54: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Twig templates"Twig is a modern template engine for PHP"

• Manual: https://twig.symfony.com• Script extension: .twig• Variables: {{ }}• Control statements: {% %}• Comments: {# #}

Rob Allen ~ @akrabat

Page 55: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Action template{% extends '@layout/default.html.twig' %}

{% block title %}Bitcoin converter{% endblock %}

{% block content %}

<h1>Bitcoin converter</h1>

<p>One BTC:</p>

{% for price in prices %}

{{ price.symbol }}

{{ price.rate_float|number_format(2, '.', ',') }}<br>

{% endfor %}

{% endblock %}

Rob Allen ~ @akrabat

Page 56: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Print variables{% extends '@layout/default.html.twig' %}

{% block title %}Bitcoin converter{% endblock %}

{% block content %}

<h1>Bitcoin converter</h1>

<p>One BTC:</p>

{% for price in prices %}

{{ price.symbol }}

{{ price.rate_float|number_format(2, '.', ',') }}<br>

{% endfor %}

{% endblock %}

Rob Allen ~ @akrabat

Page 57: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Control statements{% extends '@layout/default.html.twig' %}

{% block title %}Bitcoin converter{% endblock %}

{% block content %}

<h1>Bitcoin converter</h1>

<p>One BTC:</p>

{% for price in prices %}

{{ price.symbol }}

{{ price.rate_float|number_format(2, '.', ',') }}<br>

{% endfor %}

{% endblock %}

Rob Allen ~ @akrabat

Page 58: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Template inheritance{% extends '@layout/default.html.twig' %}

{% block title %}Bitcoin converter{% endblock %}

{% block content %}

<h1>Bitcoin converter</h1>

<p>One BTC:</p>

{% for price in prices %}

{{ price.symbol }}

{{ price.rate_float|number_format(2, '.', ',') }}<br>

{% endfor %}

{% endblock %}

Rob Allen ~ @akrabat

Page 59: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Template inheritance• For cohesive look and feel

• includes default CSS, JS & structural HTML

• Build a base skeleton• Define blocks for children to override• Each child chooses which template to inherit from

Rob Allen ~ @akrabat

Page 60: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Base skeletonsrc/App/templates/layout/default.html.twig:

<!DOCTYPE html>

<html>

<head>

{% block head %}

<link rel="stylesheet" href="style.css" />

<title>{% block title %}{% endblock %} - Akrabat</title>

{% endblock %}

</head>

<body>

{% block content %}{% endblock %}

<footer>{% block footer %}&copy; 2017{% endblock %}</footer>

</body>

</html>

Rob Allen ~ @akrabat

Page 61: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Base skeletonsrc/App/templates/layout/default.html.twig:

<!DOCTYPE html>

<html>

<head>

{% block head %}

<link rel="stylesheet" href="style.css" />

<title>{% block title %}{% endblock %} - Akrabat</title>

{% endblock %}

</head>

<body>

{% block content %}{% endblock %}

<footer>{% block footer %}&copy; 2017{% endblock %}</footer>

</body>

</html>

Rob Allen ~ @akrabat

Page 62: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Base skeletonsrc/App/templates/layout/default.html.twig:

<!DOCTYPE html>

<html>

<head>

{% block head %}

<link rel="stylesheet" href="style.css" />

<title>{% block title %}{% endblock %} - Akrabat</title>

{% endblock %}

</head>

<body>

{% block content %}{% endblock %}

<footer>{% block footer %}&copy; 2017{% endblock %}</footer>

</body>

</html>

Rob Allen ~ @akrabat

Page 63: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Base skeletonsrc/App/templates/layout/default.html.twig:

<!DOCTYPE html>

<html>

<head>

{% block head %}

<link rel="stylesheet" href="style.css" />

<title>{% block title %}{% endblock %} - Akrabat</title>

{% endblock %}

</head>

<body>

{% block content %}{% endblock %}

<footer>{% block footer %}&copy; 2017{% endblock %}</footer>

</body>

</html>

Rob Allen ~ @akrabat

Page 64: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

.

Rob Allen ~ @akrabat

Page 65: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Adding components

Rob Allen ~ @akrabat

Page 66: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Add a form

Rob Allen ~ @akrabat

Page 67: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Add a form: HTML<form method="GET" action="/bitcoin">

<label>&pound;</label>

<input name="amount" value="{{ amount }}">

<button>Convert</button>

</form>

<p>&pound;{{amount}} is {{ bitcoins|number_format(6) }} BTC

Rob Allen ~ @akrabat

Page 68: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Add a form: HTML<form method="GET" action="/bitcoin">

<label>&pound;</label>

<input name="amount" value="{{ amount }}">

<button>Convert</button>

</form>

<p>&pound;{{amount}} is {{ bitcoins|number_format(6) }} BTC

Rob Allen ~ @akrabat

Page 69: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Add a form: HTML<form method="GET" action="/bitcoin">

<label>&pound;</label>

<input name="amount" value="{{ amount }}">

<button>Convert</button>

</form>

<p>&pound;{{amount}} is {{ bitcoins|number_format(6) }} BTC

Rob Allen ~ @akrabat

Page 70: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Add a form: HTML<form method="GET" action="/bitcoin">

<label>&pound;</label>

<input name="amount" value="{{ amount }}">

<button>Convert</button>

</form>

<p>&pound;{{amount}} is {{ bitcoins|number_format(6) }} BTC

Rob Allen ~ @akrabat

Page 71: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Add a form: HTML<form method="GET" action="/bitcoin">

<label>&pound;</label>

<input name="amount" value="{{ amount }}">

<button>Convert</button>

</form>

<p>&pound;{{amount}} is {{ bitcoins|number_format(6) }} BTC</p>

Rob Allen ~ @akrabat

Page 72: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Zend-InputFilter 

Rob Allen ~ @akrabat

Page 73: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Integration via ConfigProvider

Rob Allen ~ @akrabat

No need to run a special command line tool
composer require does the right thing for you
Saves learning new tools as composer is already well-known
Page 74: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Create an input filter$factory = new Zend\InputFilter\Factory();

$inputFilter = $factory->createInputFilter([

'amount' => [

'filters' => [

['name' => 'NumberParse'],

],

'validators' => [

[

'name' => 'GreaterThan',

'options' => ['min' => 0],

],

]

],

]);

Rob Allen ~ @akrabat

Page 75: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Create an input filter$factory = new Zend\InputFilter\Factory();

$inputFilter = $factory->createInputFilter([

'amount' => [

'filters' => [

['name' => 'ToInt'],

],

'validators' => [

[

'name' => 'GreaterThan',

'options' => ['min' => 0],

],

]

],

]);

Rob Allen ~ @akrabat

Page 76: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Create an input filter$factory = new Zend\InputFilter\Factory();

$inputFilter = $factory->createInputFilter([

'amount' => [

'filters' => [

['name' => 'ToInt'],

],

'validators' => [

[

'name' => 'GreaterThan',

'options' => ['min' => 0],

],

]

],

]);

Rob Allen ~ @akrabat

Page 77: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Create an input filter$factory = new Zend\InputFilter\Factory();

$inputFilter = $factory->createInputFilter([

'amount' => [

'filters' => [

['name' => 'ToInt'],

],

'validators' => [

[

'name' => 'GreaterThan',

'options' => ['min' => 0],

],

]

],

]);

Rob Allen ~ @akrabat

Page 78: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Create an input filter$factory = new Zend\InputFilter\Factory();

$inputFilter = $factory->createInputFilter([

'amount' => [

'filters' => [

['name' => 'ToInt'],

],

'validators' => [

[

'name' => 'GreaterThan',

'options' => ['min' => 0],

],

]

],

]);

Rob Allen ~ @akrabat

Page 79: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Validating request data1.Retrieve data from Request object2.Pass to InputFilter3.Call isValid()4.Retrieve sanitized, valid data using getValues()5.Use getMessages() to find out what failed

Rob Allen ~ @akrabat

Page 80: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Validating request datapublic function handle(ServerRequestInterface $request)

{

$requestData = $request->getQueryParams();

$this->inputFilter->setData($requestData);

if ($this->inputFilter->isValid()) {

/* request data is valid */

$values = $this->inputFilter->getValues();

$btc = $this->btcService->convert($values['amount']);

} else {

/* request data is invalid */

$errors = $this->inputFilter->getMessages();

}

Rob Allen ~ @akrabat

Page 81: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Validating request datapublic function handle(ServerRequestInterface $request)

{

$requestData = $request->getQueryParams();

$this->inputFilter->setData($requestData);

if ($this->inputFilter->isValid()) {

/* request data is valid */

$values = $this->inputFilter->getValues();

$btc = $this->btcService->convert($values['amount']);

} else {

/* request data is invalid */

$errors = $this->inputFilter->getMessages();

}

Rob Allen ~ @akrabat

Page 82: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Validating request datapublic function handle(ServerRequestInterface $request)

{

$requestData = $request->getQueryParams();

$this->inputFilter->setData($requestData);

if ($this->inputFilter->isValid()) {

/* request data is valid */

$values = $this->inputFilter->getValues();

$btc = $this->btcService->convert($values['amount']);

} else {

/* request data is invalid */

$errors = $this->inputFilter->getMessages();

}

Rob Allen ~ @akrabat

Page 83: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Validating request datapublic function handle(ServerRequestInterface $request)

{

$requestData = $request->getQueryParams();

$this->inputFilter->setData($requestData);

if ($this->inputFilter->isValid()) {

/* request data is valid */

$values = $this->inputFilter->getValues();

$btc = $this->btcService->convert($values['amount']);

} else {

/* request data is invalid */

$errors = $this->inputFilter->getMessages();

}

Rob Allen ~ @akrabat

Page 84: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Validating request datapublic function handle(ServerRequestInterface $request)

{

$requestData = $request->getQueryParams();

$this->inputFilter->setData($requestData);

if ($this->inputFilter->isValid()) {

/* request data is valid */

$values = $this->inputFilter->getValues();

$btc = $this->btcService->convert($values['amount']);

} else {

/* request data is invalid */

$errors = $this->inputFilter->getMessages();

}

Rob Allen ~ @akrabat

Page 85: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Summary

Rob Allen ~ @akrabat

Expressive is a microframework: PSR-7 routing, dispatching, errors, PSR-15 middleware
Rich ecosystem of components integrated via ConfigProvider mechanism
Page 86: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Resources• https://docs.zendframework.com/zend-expressive/• https://github.com/zendframework/

• https://akrabat.com/category/zend-expressive/• https://framework.zend.com/blog

• Zend Expressive Essentials by Matt Setter

Rob Allen ~ @akrabat

Page 87: Building Websites with Zend Expressive 3 · 2018-02-13 · Building Websites with Zend Expressive 3 Rob Allen, Nineteen Feet February 2018 ~ @akrabat

Thank you!

https://joind.in/talk/52ee1

Rob Allen ~ @akrabat