47
Zend Framework 3 Rostislav Mykhajliw TrueSocialMetrics Inc.

Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

  • Upload
    fwdays

  • View
    405

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Zend Framework 3Rostislav MykhajliwTrueSocialMetrics Inc.

Page 2: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

DecouplingStandards

PerformanceCleanup!

Page 3: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Components

"zendframework/zend-mvc": "*", "zendframework/zend-mvc-console": "*", "zendframework/zend-di": "*", "zendframework/zend-servicemanager": "*", "zendframework/zend-eventmanager": "*",

"zendframework/zendframework": "2.*",

Page 4: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

ServiceManager / DI

Page 5: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Interop\Container\ContainerInterface

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

Aura-Di, Laravel, Nette-DI, PHP-DI, Pimple, Symfony-DI, Zend-DI ...

Page 6: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

ServiceLocator - DI

Provides integration for zend-di within zend-servicemanager

"zendframework/zend-servicemanager-di": "*"

Page 7: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

ServiceLocator - build everything

public function build($name, array $options = null){ // We never cache when using "build" $name = isset($this->resolvedAliases[$name]) ? $this->resolvedAliases[$name] : $name; return $this->doCreate($name, $options);}

$serviceLocator->build(‘Customer’, [‘name’ => ‘Joe’]); // Joe

$serviceLocator->build(‘Customer’, [‘name’ => ‘Mike’]); // Mike

Never caches custom object builder through ServiceLocator

Page 8: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

ServiceLocatorAwareInterface - has gone ...

PluginManagerLocator - removed

You have to inject all your dependencies!

final class AuthentificationController extends AbstractActionController{ private $service = $service;

public function __construct(AuthentificationService $service) { $this->service = $service; }}

Page 9: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

FactoryInterface - has gone (deprecated) ...

Zend\ServiceManager\FactoryInterface - zf2Zend\ServiceManager\Factory\FactoryInterface - zf3

WAT?

Page 10: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

FactoryInterface - has gove (deprecated) ...

final class AuthentificationPluginFactory{ public function getContainer(ServiceLocatorInterface $serviceLocator) { // zf2 if ($serviceLocator instanceof AbstractPluginManager) { return $serviceLocator->getServiceLocator(); } // zf3 return $serviceLocator; }

public function __invoke(ServiceLocatorInterface $serviceLocator) { $container = $this->getContainer($serviceLocator); $repository = $container->get('RepositoryCustomer'); return new AuthentificationPlugin($repository); }}

Page 11: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

EventManager

Page 12: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

EventManager

StaticEventManager - removed!

GlobalEventManager static methods - GONE!

SharedEventAggregateAwareInterface - removed!

Page 13: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

EventManager

HALLELUJAH!(c) gifly.com

Page 14: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

EventManager

$application = $e->getApplication();$eventManager = $application->getEventManager()$sharedEvenManager = $eventManager->getSharedManager();

ZF2

ZF3

$sharedEvenManager instanceof SharedEventAggregateAwareInterface

!($sharedEvenManager instanceof SharedEventAggregateAwareInterface)

Page 15: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

PSR-7 / Middleware

Page 16: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

PSR-7 - HTTP Message Interface

function (RequestInterface $request) : ResponseInterface

Page 17: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware

Authentification

App

Session

request response

Page 18: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware

function ($request, $response, $next){ return $next( $request, $response );}

Page 19: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware

Zend DiactorosPSR-7 implementation

Zend Stratigilitymiddleware pipes

Zend Expressivemicro framework on top of Zend Diactoros + Zend Stratigility

Page 20: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware pipes are AWESOME!

$app = new Zend\Stratigility\MiddleWarePipe();

$app->pipe($sessionManager); // always call$app->pipe('/blog', $blogMiddleware);$app->pipe('/api', $apiMiddleware);$app->pipe($myCoreApp);

Page 21: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware pipes are AWESOME!

$apiApp = new Zend\Stratigility\MiddleWarePipe();$apiApp->pipe($tokenValidation);$apiApp->pipe($versionValidation);$apiApp->pipe($apiMiddleware);

$myApp->pipe($sessionManager); // always call$myApp->pipe('/blog', $blogMiddleware);$myApp->pipe($myCoreApp);

$app = new Zend\Stratigility\MiddleWarePipe();$app->pipe(‘/api’, $apiApp);$app->pipe($myApp);

Page 22: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware pipes error handling

$errorhandler = function($error, $request, $response, $next) { return $response->end('Internal error:' . $error);}

$app = new Zend\Stratigility\MiddleWarePipe();$app->pipe('/api', $apiMiddleware);$app->pipe($errorhandler);

Page 23: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

JSON + ENCRYPTION

JWT

Page 24: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware - JWT

{ "alg": "HS256", "typ": "JWT"}

{ "user": "John Dow", "role": "admin"}

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

HEADER DATA SIGNATURE

SHA256 (HEADER + DATA + SECRET)

Page 25: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware - Session + JWT =

PLUSES

Overhead ~ 400 bytes cookies

● - 20 ms on page load (it’s memcache session overhead)● Scalability● Independent of storage

Page 26: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Middleware - session

"ocramius/psr7-session" : "*""necromant2005/tt-serverless-session" : "*"

Page 27: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Zend Expressive

Page 28: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

DIAura-DIPimpleZend-DI...

ROUTERAura-RouteFastRouteZend-Router...

TEMPLATE

TwigPlatesZend-View...

Standalone symphony

Page 29: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Expressive

Page 30: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Expressivecomposer create-project zendframework/zend-expressive-skeleton expressive

Which router do you want to use? [1] Aura.Router [2] FastRoute [3] Zend Router

Which container do you want to use for dependency injection? [1] Aura.Di [2] Pimple [3] Zend ServiceManager

Which template engine do you want to use? [1] Plates [2] Twig [3] Zend View composer serve

Page 31: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Expressive

$app = AppFactory::create();$app->get('/', $blogApp);$app->post('/trackback', 'TrackBack');$app->put('/post/{id}', 'ReplacePost') ->setOptions([ 'tokens' => [ 'id' => '\d+' ], ]);$app->delete('/post/{id}', 'DeletePost') ->setOptions([ 'tokens' => [ 'id' => '\d+' ], ]);$app->patch('/trackback');$app->get('/api', function($req, $res, $next) { return new JsonResponse(['ack' => time()]);});$app->run();

You can reach the same through config!

Page 32: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Expressive

namespace App\Action;

class MyAction{ public function __invoke($request, $response, callable $next) { $query = $request->getQueryParams(); $message = $query['message'];

return $response->getBody()->write( 'My very unique message ' . $message ); }}

Which error handler do you want to use during development? [1] Whoops [n] None of the above

Page 33: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Expressive - PIPES

$blog = new BlogMiddleware();$api = AppFactory::create();

$app = AppFactory::create();$app->pipe('/api', $api);$app->pipe('/blog', $blog);

$app->run();

Page 34: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Expressive - ErrorHandling

"filp/whoops": "*"

● Flexible, stack-based error handling● No required dependencies● Simple API for dealing with exceptions, trace frames

& their data● Includes handlers for different response formats

(JSON, XML, SOAP)

Page 35: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"
Page 36: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Performance

Page 37: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Performance

PHP7

New Data structures

Strict Types

Closures / Traits

Page 38: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Performance

ServiceLocator - 4x faster

EventManager - 10x faster

Routing - 2x faster

Hello world! - 7x times faster

Page 39: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

2x faster page loading

Page 40: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

3x less memory

Page 41: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Tests

Page 42: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Tests - straight from the heart manual

class AlbumControllerTest extends AbstractHttpControllerTestCase{ public function setUp() { $this->setApplicationConfig(include 'config/application.config.php'); parent::setUp(); } public function testAlbum() {

$this->dispatch('/album');$this->assertResponseStatusCode(200);

}}

Page 43: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Tests - straight from the heart manual

class AlbumControllerTest extends AbstractHttpControllerTestCase{ public function setUp() { $this->setApplicationConfig(include 'config/application.config.php'); parent::setUp(); } public function testAlbum() {

$this->dispatch('/album');$this->assertResponseStatusCode(200);

}}

Page 44: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Tests - works

class RedirectControllerTest extends TestCaseController{ public function testRedirectNonAuthAction() { $controller = new RedirectController(); (new EnvironmentBuilder($this))->build($controller, []);

$res = $controller->redirectAction(); $this->assertEquals(['/analytic/metric?ga=redirect-wrong'], $res); }}

Page 45: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

Tests - works

public function testRedirectAuthAndViewReffererAction() { $controller = new RedirectController(); (new EnvironmentBuilder($this))->build($controller, [ ['name' => 'Request', 'options' => [ 'query' => ['refferer' => 'http://x.com/zzz'], 'server' => ['HTTP_HOST' => 'x.com'], ],

], ]); $view = $controller->redirectAction(); $this->assertInstanceOf('Zend\View\Model\ViewModel', $view); $this->assertEquals('http://x.com/zzz', $view->refferer); }

Page 46: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

"necromant2005/tt-test" : "*"

Page 47: Ростислав Михайлив "Zend Framework 3 - evolution or revolution"

QUESTIONS ?