Upload
fwdays
View
405
Download
0
Embed Size (px)
Citation preview
Zend Framework 3Rostislav MykhajliwTrueSocialMetrics Inc.
DecouplingStandards
PerformanceCleanup!
Components
"zendframework/zend-mvc": "*", "zendframework/zend-mvc-console": "*", "zendframework/zend-di": "*", "zendframework/zend-servicemanager": "*", "zendframework/zend-eventmanager": "*",
"zendframework/zendframework": "2.*",
ServiceManager / DI
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 ...
ServiceLocator - DI
Provides integration for zend-di within zend-servicemanager
"zendframework/zend-servicemanager-di": "*"
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
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; }}
FactoryInterface - has gone (deprecated) ...
Zend\ServiceManager\FactoryInterface - zf2Zend\ServiceManager\Factory\FactoryInterface - zf3
WAT?
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); }}
EventManager
EventManager
StaticEventManager - removed!
GlobalEventManager static methods - GONE!
SharedEventAggregateAwareInterface - removed!
EventManager
HALLELUJAH!(c) gifly.com
EventManager
$application = $e->getApplication();$eventManager = $application->getEventManager()$sharedEvenManager = $eventManager->getSharedManager();
ZF2
ZF3
$sharedEvenManager instanceof SharedEventAggregateAwareInterface
!($sharedEvenManager instanceof SharedEventAggregateAwareInterface)
PSR-7 / Middleware
PSR-7 - HTTP Message Interface
function (RequestInterface $request) : ResponseInterface
Middleware
Authentification
App
Session
request response
Middleware
function ($request, $response, $next){ return $next( $request, $response );}
Middleware
Zend DiactorosPSR-7 implementation
Zend Stratigilitymiddleware pipes
Zend Expressivemicro framework on top of Zend Diactoros + Zend Stratigility
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);
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);
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);
JSON + ENCRYPTION
JWT
Middleware - JWT
{ "alg": "HS256", "typ": "JWT"}
{ "user": "John Dow", "role": "admin"}
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
HEADER DATA SIGNATURE
SHA256 (HEADER + DATA + SECRET)
Middleware - Session + JWT =
PLUSES
Overhead ~ 400 bytes cookies
● - 20 ms on page load (it’s memcache session overhead)● Scalability● Independent of storage
Middleware - session
"ocramius/psr7-session" : "*""necromant2005/tt-serverless-session" : "*"
Zend Expressive
DIAura-DIPimpleZend-DI...
ROUTERAura-RouteFastRouteZend-Router...
TEMPLATE
TwigPlatesZend-View...
Standalone symphony
Expressive
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
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!
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
Expressive - PIPES
$blog = new BlogMiddleware();$api = AppFactory::create();
$app = AppFactory::create();$app->pipe('/api', $api);$app->pipe('/blog', $blog);
$app->run();
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)
Performance
Performance
PHP7
New Data structures
Strict Types
Closures / Traits
Performance
ServiceLocator - 4x faster
EventManager - 10x faster
Routing - 2x faster
Hello world! - 7x times faster
2x faster page loading
3x less memory
Tests
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);
}}
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);
}}
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); }}
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); }
"necromant2005/tt-test" : "*"
QUESTIONS ?