Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Zend/Expressive 3 – The Next Generation

179 Aufrufe

Veröffentlicht am

After the PSR-15 was finally published in the spring of 2018, the micro framework Zend/Expressive has archieved the next stage with its 3.0 release. Zend/Expressive suits all kinds of applications perfectly: from classic full-stack web applications via REST services through to special applications like PHP-based Alexa Skills. The third version of the micro framework based on Middleware can be your means of choice. This session introduces all the innovations in Zend/Expressive 3, presents different application possibilities, and demonstrates how to migrate from older Zend/Expressive versions.

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Zend/Expressive 3 – The Next Generation

  1. 1. 1 / 70 ZendExpressive 3 The Next Generation
  2. 2. 2 / 70 Ralf Eggert CEO Travello GmbH PHP Developer Alexa Champion
  3. 3. 3 / 70 Some definitions
  4. 4. 4 / 70 PSR PHP Standards Recommendations By the PHP Framework Interop Group https://www.php-fig.org/
  5. 5. 5 / 70 PSR-7 HTTP Message Interface HTTP Request & Response, Streams, Uris, Uploads https://www.php-fig.org/psr/psr-7/
  6. 6. 6 / 70 PSR-11 Container interface Dependency Injection Container https://www.php-fig.org/psr/psr-11/
  7. 7. 7 / 70 PSR-15 HTTP Server Request Handlers Request Handlers & Middleware https://www.php-fig.org/psr/psr-15/
  8. 8. 8 / 70 Some questions
  9. 9. 9 / 70 Question 1: Who is using the Zend Framework in general?
  10. 10. 10 / 70 Question 2: Who is using ZendExpressive in particular? Which version? (1/2/3)
  11. 11. 11 / 70 Question 3: What kind of applications have you built with ZendExpressive so far?
  12. 12. 12 / 70 From ZE1 to ZE3
  13. 13. 13 / 70 28/01/2016 ZE1 Released Focus PSR-7
  14. 14. 14 / 70 28/01/2016 07/03/2017 ZE1 Released Focus PSR-7 ZE2 Released Focus PSR-11
  15. 15. 15 / 70 28/01/2016 07/03/2017 16/03/2018 ZE1 Released Focus PSR-7 ZE2 Released Focus PSR-11 ZE3 Released Focus PSR-15
  16. 16. 16 / 70 28/01/2016 ??/??/201907/03/2017 16/03/2018 ZE1 Released Focus PSR-7 ZE2 Released Focus PSR-11 ZE3 Released Focus PSR-15 ZE4 Released Focus ???
  17. 17. 17 / 70 28/01/2016 07/03/2017 16/03/2018 ZE1 Released Focus PSR-7 ZE2 Released Focus PSR-11 ZE3 Released Focus PSR-15 Just kidding!
  18. 18. 18 / 70 ZendExpressive 1 PSR-7 compatible Middleware based Microframework Support for various router, DI container and template solutions
  19. 19. 19 / 70 ZendExpressive 2 Added PSR-11 support, programmatic pipelines, improved error handling, modular applications and development tooling to the mix.
  20. 20. 20 / 70 ZendExpressive 3 Extended with PSR-15 support, requires PHP 7.1, massive internal refactoring and adds new components for session, CSRF, flash messages, etc.
  21. 21. 21 / 70 ZendExpressive Evolution ZE1 ZE2 ZE3 Development Focus PSR-7 PSR-11 PSR-15 Minimal PHP Version 5.6 or 7.0 5.6 or 7.0 7.1 (7.2 Support) Highlight First release Programmatic pipelines New components
  22. 22. 22 / 70 From Actions to Handlers
  23. 23. 23 / 70 namespace PizzaAction; use PsrHttpMessageResponseInterface; use PsrHttpMessageServerRequestInterface; use PizzaModelRepositoryPizzaRepositoryInterface; 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] ) ); } } ZE1
  24. 24. 24 / 70 namespace PizzaAction; use InteropHttpServerMiddlewareDelegateInterface; use InteropHttpServerMiddlewareMiddlewareInterface as ServerMiddlewareInterface; use PsrHttpMessageServerRequestInterface; use PizzaModelRepositoryPizzaRepositoryInterface; class ShowIntroAction implements ServerMiddlewareInterface { public function process( ServerRequestInterface $request, DelegateInterface $delegate ) { $pizzas = $this->pizzaRepository->getPizzas(); return new HtmlResponse( $this->renderer->render( 'pizza::intro', ['pizzas' => $pizzas] ) ); } } ZE2
  25. 25. 25 / 70 namespace PizzaAction; use PsrHttpMessageResponseInterface; use PsrHttpMessageServerRequestInterface; use PsrHttpServerRequestHandlerInterface; use PizzaModelRepositoryPizzaRepositoryInterface; class ShowIntroHandler implements RequestHandlerInterface { public function handle( ServerRequestInterface $request ) : ResponseInterface { $pizzas = $this->pizzaRepository->getPizzas(); return new HtmlResponse( $this->renderer->render( 'pizza::intro', ['pizzas' => $pizzas] ) ); } } ZE3
  26. 26. 26 / 70 ZE3 Request Handlers Evolved from ZE1 action classes to ZE3 request handlers Implement PSR-15 interfaces now Easy migration path
  27. 27. 27 / 70 From configurable to programmatic middleware pipelines
  28. 28. 28 / 70 // /config/autoload/middleware-pipeline.php return [ 'middleware_pipeline' => [ 'always' => [ 'middleware' => [ ServerUrlMiddleware::class, ], 'priority' => 10000, ], 'routing' => [ 'middleware' => [ ApplicationFactory::ROUTING_MIDDLEWARE, UrlHelperMiddleware::class, ApplicationFactory::DISPATCH_MIDDLEWARE, ], 'priority' => 1, ], 'error' => [ 'middleware' => [], 'error' => true, 'priority' => -10000, ], ], ]; ZE1
  29. 29. 29 / 70 // /config/pipeline.php $app->pipe(ErrorHandler::class); $app->pipe(ServerUrlMiddleware::class); $app->pipeRoutingMiddleware(); $app->pipe(ImplicitHeadMiddleware::class); $app->pipe(ImplicitOptionsMiddleware::class); $app->pipe(UrlHelperMiddleware::class); $app->pipeDispatchMiddleware(); $app->pipe(NotFoundHandler::class); ZE2
  30. 30. 30 / 70 // /config/pipeline.php return function ( Application $app, MiddlewareFactory $factory, ContainerInterface $container ) : void { $app->pipe(ErrorHandler::class); $app->pipe(ServerUrlMiddleware::class); $app->pipe(RouteMiddleware::class); $app->pipe(ImplicitHeadMiddleware::class); $app->pipe(ImplicitOptionsMiddleware::class); $app->pipe(MethodNotAllowedMiddleware::class); $app->pipe(UrlHelperMiddleware::class); $app->pipe(DispatchMiddleware::class); $app->pipe(NotFoundHandler::class); }; ZE3
  31. 31. 31 / 70 // /module/Application/src/Config/PipelineDelegatorFactory.php namespace ApplicationConfig; class PipelineDelegatorFactory implements DelegatorFactoryInterface { public function __invoke( ContainerInterface $container, $name, callable $callback, array $options = null ) { $application = $callback(); $application->pipe(ErrorHandler::class); $application->pipe(ServerUrlMiddleware::class); $application->pipe(RouteMiddleware::class); $application->pipe(ImplicitHeadMiddleware::class); $application->pipe(ImplicitOptionsMiddleware::class); $application->pipe(MethodNotAllowedMiddleware::class); $application->pipe(UrlHelperMiddleware::class); $application->pipe(DispatchMiddleware::class); $application->pipe(NotFoundHandler::class); return $application; } }; ZE3
  32. 32. 32 / 70 ZE3 Middleware Pipeline Evolved from configuration arrays to delegator factory classes Medium migration path
  33. 33. 33 / 70 Evolving of the pipeline middleware
  34. 34. 34 / 70 namespace ZendExpressiveHelper; use PsrHttpMessageResponseInterface; use PsrHttpMessageServerRequestInterface; use ZendExpressiveRouterRouteResult; class UrlHelperMiddleware { public function __invoke( ServerRequestInterface $request, ResponseInterface $response, callable $next ) { $result = $request->getAttribute(RouteResult::class, false); if ($result instanceof RouteResult) { $this->helper->setRouteResult($result); } return $next($request, $response); } } ZE1
  35. 35. 35 / 70 namespace ZendExpressiveHelper; use InteropHttpServerMiddlewareDelegateInterface; use InteropHttpServerMiddlewareMiddlewareInterface as ServerMiddlewareInterface; use PsrHttpMessageServerRequestInterface; use ZendExpressiveRouterRouteResult; class UrlHelperMiddleware implements ServerMiddlewareInterface { public function process( ServerRequestInterface $request, DelegateInterface $delegate ) { $result = $request->getAttribute(RouteResult::class, false); if ($result instanceof RouteResult) { $this->helper->setRouteResult($result); } return $delegate->process($request); } } ZE2
  36. 36. 36 / 70 namespace ZendExpressiveHelper; use PsrHttpMessageResponseInterface; use PsrHttpMessageServerRequestInterface; use PsrHttpServerMiddlewareInterface; use PsrHttpServerRequestHandlerInterface; use ZendExpressiveRouterRouteResult; class UrlHelperMiddleware implements MiddlewareInterface { public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) : ResponseInterface { $result = $request->getAttribute(RouteResult::class, false); if ($result instanceof RouteResult) { $this->helper->setRouteResult($result); } return $handler->handle($request); } } ZE3
  37. 37. 37 / 70 ZE3 Pipeline Middleware Evolved to full PSR-15 interface implementation Easy migration path
  38. 38. 38 / 70 Evolving of the front controller
  39. 39. 39 / 70 if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)) ) { return false; } chdir(dirname(__DIR__)); require 'vendor/autoload.php'; /** @var InteropContainerContainerInterface $container */ $container = require 'config/container.php'; /** @var ZendExpressiveApplication $app */ $app = $container->get(ZendExpressiveApplication::class); $app->run(); ZE1
  40. 40. 40 / 70 if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) { return false; } chdir(dirname(__DIR__)); require 'vendor/autoload.php'; call_user_func(function () { /** @var PsrContainerContainerInterface $container */ $container = require 'config/container.php'; /** @var ZendExpressiveApplication $app */ $app = $container->get(ZendExpressiveApplication::class); require 'config/pipeline.php'; require 'config/routes.php'; $app->run(); }); ZE2
  41. 41. 41 / 70 if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) { return false; } chdir(dirname(__DIR__)); require 'vendor/autoload.php'; (function () { /** @var PsrContainerContainerInterface $container */ $container = require 'config/container.php'; /** @var ZendExpressiveApplication $app */ $app = $container->get(ZendExpressiveApplication::class); $factory = $container->get(ZendExpressiveMiddlewareFactory::class); (require 'config/pipeline.php')($app, $factory, $container); (require 'config/routes.php')($app, $factory, $container); $app->run(); })(); ZE3
  42. 42. 42 / 70 ZE3 Front Controller From polluting the global namespace to self-called anonymous function with its own scope Easy migration path
  43. 43. 43 / 70 New ZE3 components
  44. 44. 44 / 70 Authentication Middleware for Authentication with Basic Auth, OAuth2, Session and ZendAuthentication
  45. 45. 45 / 70 Authorization Middleware for Authorization with adapters for both RBAC and ACL authorization
  46. 46. 46 / 70 Session Middleware with PSR-7 support, lazy sessions and ext-session extension
  47. 47. 47 / 70 CSRF Middleware and guards for Cross-Site Request Forgery (CSRF) protection
  48. 48. 48 / 70 Flash Messages Middleware and support for Flash Messages
  49. 49. 49 / 70 HttpHandlerRunner Utilities emitting PSR-7 responses and running PSR-15 server request handlers
  50. 50. 50 / 70 Swoole Expressive support for Swoole, the PHP asynchronous programming framework
  51. 51. 51 / 70 HAL JSON Expressive support for Hypertext Application Language (used by Apigility)
  52. 52. 52 / 70 Problem details Expressive support for problem details format (used by Apigility)
  53. 53. 53 / 70 Components More than 30 components and helper repositories for the ZendExpressive cosmos so far And don't forget the other Zend Framework components
  54. 54. 54 / 70 Applications
  55. 55. 55 / 70 Applications Which kind of applications can be build with ZendExpressive?
  56. 56. 56 / 70 Applications Classical websites
  57. 57. 57 / 70 Applications Backends
  58. 58. 58 / 70 Applications RESTful APIs
  59. 59. 59 / 70 Applications Alexa Skills
  60. 60. 60 / 70 phlexa PHP Framework to build voice applications for Amazon Alexa (built with ZE3) https://www.phoice.tech/phlexa
  61. 61. 61 / 70 Applications So many opportunities! What are you planning to build next?
  62. 62. 62 / 70 Migration to ZE3
  63. 63. 63 / 70 Migration to ZE3 Migrate your actions to handlers (PSR-15 interfaces)
  64. 64. 64 / 70 Migration to ZE3 Migrate to programmatic middleware pipeline and maybe even introduce a delegator factory
  65. 65. 65 / 70 Migration to ZE3 Migrate your pipeline middleware classes (PSR-15 interfaces)
  66. 66. 66 / 70 Migration to ZE3 Check your current front controller
  67. 67. 67 / 70 Migration to ZE3 Start using the new Expressive components
  68. 68. 68 / 70 Conclusion
  69. 69. 69 / 70 ZendExpressive 3 The Next Generation is ready to start!
  70. 70. 70 / 70 Thanks! ralf@travello.de https://www.travello.de

×