Post on 10-Jan-2017
1
ZEND\EXPRESSIVE höher schneller weiter
CODE INSIDE
2
RALF EGGERT
TrainerBerater
Autor
Insulaner
Speaker
Entwickler
ZF1seit 2006
ZF2seit 2012
ZF3seit 2016
GF
Travello
GmbH
www.ralfeggert.de
3
1 PSR-7 / Middleware
2Middleware für Aktionen3
Zend\Expressive Überblick
Middleware für die Pipeline4Und was ist mit Tee MVC?5
4
1 PSR-7 / Middleware
5
WAS ISTPSR-7?
6
PSR4
Autoload PSR2
CodingPSR1Coding
PSR3Logging PSR6
Caching
PSR7HTTP
PHP-FIGwww.phpfig.org
PSR11
???PSR14
???
PSR15
???
7
<?phpnamespace Psr\Http\Message;
interface MessageInterface{ public function getProtocolVersion(); public function withProtocolVersion($version); public function getHeaders(); public function hasHeader($name); public function getHeader($name); public function getHeaderLine($name); public function withHeader($name, $value); public function withAddedHeader($name, $value); public function withoutHeader($name); public function getBody(); public function withBody(StreamInterface $body);}
PS
R-7
ME
SS
AG
E IN
TE
RF
AC
E
8
<?phpnamespace Psr\Http\Message;
interface RequestInterface extends MessageInterface {}
interface ServerRequestInterface extends RequestInterface {}
interface ResponseInterface extends MessageInterface {}
interface StreamInterface {}
interface UploadedFileInterface {}
interface UriInterface{}
PS
R-7
WE
ITE
RE
INT
ER
FA
CE
S
9
WAS ISTMIDDLEWARE?
10
CLIENT WEBSERVER
HTTPREQUEST
HTTPRESPONSE
HTTP
11
MIDDLEWARE
HTTP
REQUEST
HTTP
RESPONSEMIDDLEWARE
12
MIDDLEWAREPIPELINE
HTTP
REQUEST
HTTP
RESPONSE MIDDLEWARE 1 MIDDLEWARE 2 MIDDLEWARE 3
13
<?phpinterface LambdaMiddlewareInterface{ /** * @param RequestInterface $request * @return ResponseInterface */ public function __invoke($request);}
LA
MB
DA
M
IDD
LE
WA
RE
INT
ER
FA
CE
14
<?phpinterface InjectedResponseMiddlewareInterface{ /** * @param RequestInterface $request * @param ResponseInterface $response * @return ResponseInterface */ public function __invoke($request, $response);}
INJE
CT
ED
RE
SP
ON
SE
MID
DL
EW
AR
EIN
TE
RF
AC
E
15
<?phpinterface InjectedNextMiddlewareInterface{ /** * @param RequestInterface $request * @param ResponseInterface $response * @param callable $next * @return ResponseInterface */ public function __invoke( $request, $response, $next = null );}
INJE
CT
ED
NE
XT
M
IDD
LE
WA
RE
INT
ER
FA
CE
used by ZF3
16
2 Zend\Expressive Überblick
17
FRAMEWORK SILOS
18
FRAMEWORK SILOS
19
ZEND\DIACTOROS
ZEND\STRATIGILITY
ZEND\EXPRESSIVE
ZF KOMPONENTEN
PSR-7
MIDDLEWARE
MIDDLEWAREAPPLICATIONS
20
ROUTER DI CONTAINER TEMPLATERENDERER
ERRORHANDLER
Aura.Router
FastRoute
Zend\Router
Weitere Router
Aura.DI
Pimpleinterop
Zend\ServiceManager
WeitereDI Container
Plates
Twig
Zend\View
WeitereTemplateEngine
Whoops
WeitererErrorHandler
ZEND\EXPRESSIVEZUTATEN
21
PERFORMANCEMESSDATEN
Gemessen im April 2016 mit der Zend\Expressive Skeleton 1.0.1
AD = Aura.DI, AR = Aura.Router, FR = FastRoute, ZR = Zend\Router, ZS = Zend\ServiceManager, ZV = Zend\View
Laufzeit (ms) 31,8 106,5 43,8 31,9 103,8 44,9 42,7 117,2 56,1 35,6 31,3
Router FR FR FR AR AR AR ZR ZR ZR FR FR
DI Container ZS ZS ZS ZS ZS ZS ZS ZS ZS AD Pimple
Renderer Plates Twig ZV Plates Twig ZV Plates Twig ZV Plates Plates
22
PERFORMANCEERKENNTNISSE
AD = Aura.DI, AR = Aura.Router, FR = FastRoute, ZR = Zend\Router, ZS = Zend\ServiceManager, ZV = Zend\View
AR FRZR
ROUTER
Plates
Twig
ZV
RENDERER
AD Pimple ZS
DI CONTAINER
23
PERFORMANCEFAZIT
AD = Aura.DI, AR = Aura.Router, FR = FastRoute, ZR = Zend\Router, ZS = Zend\ServiceManager, ZV = Zend\View
FR
SCHNELLSTEVARIANTE
PlatesPimple
PS: Traue keiner Statistik, die du nicht selber gefälscht hast! ;)
ZR
REINE ZFVARIANTE
ZVZS
24
INSTALLATION$ composer create-project ⏎ zendframework/zend-expressive-skeleton ⏎ /var/www/zend-expressive-skeleton$ cd /var/www/zend-expressive-skeleton$ composer serve
25
ZE
ND
\ EX
PR
ES
SIV
ESK
EL
ET
ON
AP
PL
ICA
TIO
N
26
VERZEICHNISSTRUKTUR config autoload data cache public src Application Action templates application error layout test ApplicationTest Action vendor composer.json
config autoload data cache modules Application config src Action templates application error layout test Action public vendor composer.json
MO
DU
LA
R
EIN
FA
CH
27
CO
NF
I GM
AN
AG
ER
$ composer require mtymek/expressive-config-manager
<?php// Datei /config/config.php
use Zend\Expressive\ConfigManager\ConfigManager;use Zend\Expressive\ConfigManager\PhpFileProvider;
$configManager = new ConfigManager([ Application\ConfigProvider::class, new PhpFileProvider( 'config/autoload/{{,*.}global,{,*.}local}.php' ),]);
return new ArrayObject( $configManager->getMergedConfig());
28
CO
NF
I GP
RO
VID
ER
<?php// Datei /modules/Application/src/ConfigProvider.php
namespace Application;
use Zend\Config\Factory;
class ConfigProvider{ public function __invoke() { return Factory::fromFile( __DIR__ . '/../config/module.config.php' ); }}
29
CO
MP
ON
EN
TIN
ST
AL
LE
R$ composer require ⏎ zendframework/zend-component-installer$ composer require zendframework/zend-db
<?php// Datei /config/config.php
use Zend\Expressive\ConfigManager\ConfigManager;use Zend\Expressive\ConfigManager\PhpFileProvider;
$configManager = new ConfigManager([ Zend\Db\ConfigProvider::class, Application\ConfigProvider::class, new PhpFileProvider( 'config/autoload/{{,*.}global,{,*.}local}.php' ),]);
return new ArrayObject( $configManager->getMergedConfig());
30
Middleware für Aktionen3
31
AKTIONEN BEISPIELE
32
TEMPLATE
BAUSTEINE AKTION
ROUTING
MIDDLEWARE
KONFIGURATION
33MID
DL
EW
AR
Enamespace Pizza\Action;
use Application\Template\TemplateRendererInterface;use Pizza\Model\Repository\PizzaRepositoryInterface;
class ShowIntroAction{ /* ... */
public function __invoke( ServerRequestInterface $request, ResponseInterface $response, callable $next = null ) { $pizzas = $this->pizzaRepository->getPizzas();
return new HtmlResponse( $this->renderer->render( 'pizza::intro', ['pizzas' => $pizzas] ) ); }}
34ZE
ND
\VI E
WT
EM
PL
AT
E<?php foreach ($this->pizzas as $pizza) : ?> <?php $urlShow = $this->url( 'pizza-show', ['id' => $pizza['id']] ); ?> <div class="col-md-4"> <div class="thumbnail text-center"> <a href="<?= $urlShow; ?>"> <img src="<?= $pizza['image'] ?>" title="<?= $pizza['name'] ?>"> </a> </div> </div><?php endforeach ?>
35
return [ 'routes' => [ [ 'name' => 'pizza-intro', 'path' => '/pizza', 'middleware' => Pizza\Action\ShowIntroAction::class, 'allowed_methods' => ['GET'], ], [ 'name' => 'pizza-handle-delete', 'path' => '/pizza/delete/:id', 'middleware' => Pizza\Action\DeletePizzaAction::class, 'allowed_methods' => ['POST'], 'options' => [ 'constraints' => [ 'id' => '[1-9][0-9]*', ], ], ], ],];
ZE
ND
\ RO
UT
ER
RO
UT
ING
36
namespace PizzaRest\Action;
class GetIdAction{ use PizzaRepositoryAwareTrait;
public function __invoke( ServerRequestInterface $request, ResponseInterface $response, callable $next = null ) { $pizza = $this->pizzaRepository->getSinglePizza( $request->getAttribute('id') );
if (!$pizza) { return new JsonResponse( ['err' => 'Not found'] ); } return new JsonResponse($pizza); }}
RE
ST
AK
TIO
N
37
Middleware für die Pipeline4
38
HTTP
REQUEST
HTTP
RESPONSE
ROUTING
MIDDLEWARE
URL HELPER
MIDDLEWARE
DISPATCHING
MIDDLEWARE
ZEND\EXPRESSIVEMW PIPELINE
39
HTTP
REQUEST
HTTP
RESPONSE
LOCALIZATION
MIDDLEWARE
AUTHENTICATION
MIDDLEWARE
AUTHORIZATION
MIDDLEWARE
KOMPLEXEREMW PIPELINE
40
use Zend\Expressive\Container\ApplicationFactory;use Zend\Expressive\Helper;return [ 'middleware_pipeline' => [ 'always' => [ 'middleware' => [ Helper\ServerUrlMiddleware::class, ], 'priority' => 10000, ], 'routing' => [ 'middleware' => [ ApplicationFactory::ROUTING_MIDDLEWARE, Helper\UrlHelperMiddleware::class, ApplicationFactory::DISPATCH_MIDDLEWARE, ], 'priority' => 1, ], 'error' => [ 'middleware' => [], 'error' => true, 'priority' => -10000, ], ],];
DE
FA
UL
TK
ON
FIG
UR
AT
ION
41
use I18n\Middleware\LocalizationMiddleware;use User\Authorization\AuthenticationMiddleware;use User\Authorization\AuthorizationMiddleware;use Zend\Expressive\Container\ApplicationFactory;use Zend\Expressive\Helper;
return [ 'middleware_pipeline' => [ 'always' => [ /* ... */ ], 'routing' => [ 'middleware' => [ ApplicationFactory::ROUTING_MIDDLEWARE, Helper\UrlHelperMiddleware::class, LocalizationMiddleware::class, AuthenticationMiddleware::class, AuthorizationMiddleware::class, ApplicationFactory::DISPATCH_MIDDLEWARE, ], 'priority' => 1, ], 'error' => [ /* ... */ ], ],];
KO
MP
LE
XE
RE
KO
NF
IGU
RA
TIO
N
42
namespace User\Authorization;
class AuthorizationMiddleware{ public function __invoke( ServerRequestInterface $request, ResponseInterface $response, callable $next ) { $permission = $result->getMatchedRouteName();
if (!$this->rbac->isGranted($this->role, $permission)) { if ($this->role == GuestRole::NAME) { throw new RuntimeException( 'Nicht angemeldet', 401 ); } else { throw new RuntimeException('Kein Zugriff', 403); } } return $next($request, $response); }}
AU
TH
OR
IZA
TIO
N
MI D
DL
EW
AR
E
43AU
TH
OR
IZA
TIO
NF
EH
LG
ES
CH
LA
GE
N
44
Und was ist mit Tee MVC?5
45
WARUMNOCH MVC,
WENN WIR NUN MIDDLEWARE
HABEN?
MVCMW Neues
Konzept
WenigeModule
MiddlewarePipeline
SchwerereIntegration
unerfahreneEntwickler
NeueProjekte
Migrationkomplexer
sehrperformant
erprobt& stabil
vieleModule
Migrationeinfach
LeichteIntegration
erfahreneEntwickler
EventManager
Bestandsprojekte
wenigerperformant
Zukunft Gegenwart
47
TUTORIAL
https://github.com/RalfEggert/zendexpressivetutorial
48
ACHTUNG! WERBUNG!
www.zendframeworkbuch.de
49
DANKE!FRAGEN?
50
1Digging In
von Zach DischnerFlickr CC BY 2.0 5
Pipesvon Leonid Mamchenkov
Flickr CC BY 2.0
17Monument valleyvon Moyan BrennFlickr CC BY 2.0
30»and... action«
von Latin SnakeFlickr CC BY 2.0
44Und was ist mit Tee?
aus der Giotto WerbungYouTube
37Pipeline
von jasonwoodhead23Flickr CC BY 2.0
4A flowery meadowvon Michael FigielFlickr CC BY 2.0
BILDNACHWEIS
49free high res texture 380
von Caleb KimbroughFlickr CC BY 2.0