SlideShare une entreprise Scribd logo
1  sur  95
Télécharger pour lire hors ligne
O que esperar do Zend Framework 3
Flávio Gomes da Silva Lisboa
www.fgsl.eti.br
Quem sou eu?
● Bacharel em Ciência da Computação com pós-graduação em Aplicações
Corporativas usando Orientação a Objetos e Tecnologia Java pela
Universidade Tecnológica Federal do Paraná. Programador formado pelo
Centro Estadual de Educação Tecnológica Paula Souza.
● Chefe do setor de adequação da solução e mobilidade do projeto Expresso
3 na Coordenação Estratégica de Ações Governamentais do Serviço
Federal de Processamento de Dados (Serpro).
● Zend PHP Certified Engineer, Zend Framework Certified Engineer e Zend
Framework 2 Certified Architect.
Autor de
20132012201020092008
http://www.novatec.com.br/autores/flaviogomes/
Saindo do forno...
E em breve...
Zend Framework Componentes Poderosos para PHP 3ª edição
Criando Aplicações PHP com Zend e ExtJS
Autor também de
http://www.perse.com.br
Escreve no blog
http://romocavaleirodoespaco.blogspot.com.br/
Sumário
● Componentes
● HTTP, PSR-7 e Middleware
● PHP 7 e PHP 5.5
ZF3
● Ênfase em componentes
ZF3
● Ênfase em componentes
● Foco em HTTP, via PSR-7 e middleware
ZF3
● Ênfase em componentes
● Foco em HTTP, via PSR-7 e middleware
● Otimizado para PHP 7, mas suporta PHP 5.5+
ZF3
● Ênfase em componentes
● Foco em HTTP, via PSR-7 e middleware
● Otimizado para PHP 7, mas suporta PHP 5.5+
● Lançamento previsto para...
Componentes
ZF1: o passado
● Componentes eram desenvolvidos dentro do
repositório do framework, e
ZF1: o passado
● Componentes eram desenvolvidos dentro do
repositório do framework, e
● Eram instaláveis somente com o framework
inteiro.
ZF2: o presente
● Componentes são desenvolvidos dentro do
repositório do framework, e
● Podem ser instalados individualmente
(Composer, GIT).
ZF 2.5: o presente
● Não há mais pacotes de instalação.
● O repositório ZF depende dos componentes.
Instale só o que vai usar
{
"require": {
"zendframework/zend-authentication": "^2.5",
"zendframework/zend-cache": "^2.5",
"zendframework/zend-captcha": "^2.5",
"etc": "*"
}
}
Por que?
Fácil manutenção
● Permite mais times com direitos de alterar
código de componentes
● Permite um destino determinístico de
repositórios
Esqueletos específicos para casos
de uso
● Entrega somente serviços?
● Precisa de desempenho?
● Precisa de tudo?
Haverá um esqueleto para isso!
HTTP, PSR-7 e Middleware
HTTP é o fundamento da Web
● Um cliente envia uma requisição
● Um servidor devolve uma resposta
Mensagens HTTP
GET /path HTTP/1.1
Host: example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{"foo":"bar"}
Requisição
Resposta
Frameworks modelam mensagens
Mas cada framework faz isso diferente
$method = $request->getMethod();
$method = $request->getRequestMethod();
$method = $request->method;
Requisição
$method = $request->getMethod();
$accept = $request->getHeader('Accept');
$path = $request->getUri()->getPath();
$controller = $request->getAttribute('controller');
Resposta
$response->getBody()->write('Hello world!');
$response = $response
->withStatus(200, 'OK')
->withHeader('Content-Type', 'text/plain');
Middleware
Entre a requisição e a resposta
function (Request $request, Response $response)
{
// do some work
return $response; // same, or a new instance.
}
Uma arquitetura de terceirização
Isso parece...
Tipos de Middleware
Pilhas ou Condutores
$pipeline->pipe($middleware1); // always evaluate
$pipeline->pipe('/path', $middleware2); // only if path matches
$pipeline->pipe('/different/path', $middleware3);
$response = $pipeline->run();
Estilo Cebola
class Outer
{
public $inner;
public function __invoke($request, $response)
{
// do some work
$response = ($this->inner)($request, $response);
// do some work
return $response;
}
}
$response = $outer($request, $response);
Estilo Lambda
function (Request $request)
{
// do some work
return $response;
}
$response = $middleware($request);
Consumindo Middleware
ZF permitirá despachar o seguinte middleware:
… e controladores ZF serão middleware.
/**
* @return Response
*/
public function (Request $request, Response $response);
Encapsulador de Middleware para ZF
$middleware = new MvcMiddlewareWrapper(
require 'config/application/config.php'
);
class MvcMiddlewareWrapper
{
public function __invoke($request, $response)
{
$app = Application::init($this->config);
return $app->dispatch($request,
$response);
}
}
Middleware como alternativa para
tempo de execução
● Desempenho
● Experiência do desenvolvedor
● Reusabilidade entre frameworks
Exemplo
$app = new Middleware();
$app->pipe('/', $homepage); // Static!
$app->pipe('/customer', $zf2Middleware); // ZF2!
$app->pipe('/products', $zf1Middleware); // ZF1!
$app->pipe('/api', $apigility); // Apigility!
$app->pipe('/user', $userMiddleware); // 3rd party!
$server->listen($app);
PSR-7 e Middleware provêem...
● Caminhos para otimização de desempenho
● Interfaces para web mais simples
● Maior interoperabilidade e potencial reuso
PHP 7 e PHP 5.5
Atualização para o PHP 5.5
● Conseguimos usar traits!
● Conseguimos usar a sintaxe curta de array!
● Conseguimos usar callable type hint!
● Conseguimos usar finally!
● Podemos usar a constante mágica ::class!
● Conseguimos usar generators!
● Conseguimos um PHP mais rápido, mais seguro!
PHP 7
Impressionante melhoria de desempenho!
Novo gerenciamento de estruturas de dados no
motor do PHP
Novas funcionalidades como declarações de tipo
para argumento e retorno
PHP 7 : Benchmark
PHP 5.6 PHP 7
Uso de memória 428 MB 33 MB
Tempo de execução 0.49 sec 0.06 sec
$a = array();
for ($i = 0; $i < 1000000; $i++) {
$a[$i] = array("hello");
}
echo memory_get_usage(true);
Bench.php
Wordpress
Frameworks
ZF3: Otimizado para PHP 7
Atualizar PHP provê melhor segurança, melhora
o desempenho e permite melhorar o framework
Certo, mas e onde está esse ZF3?
Não existe Zend Framework 3
Mas não tema!
Zend Expressive
Expressive permite que você escreva aplicações
middleware PSR-7 para a web. É um simples micro-
framework construído no topo do Stratigility, fornecendo:
● Roteamento dinâmico;
● Injeção de dependência via interoperabilidade de
containers;
● Templating;
● Manipulação de erros.
Hello World
(para index.php no web root)
// In index.php
use ZendExpressiveAppFactory;
use PsrHttpMessageResponseInterface;
use PsrHttpMessageRequestInterface;
require 'vendor/autoload.php';
$app = AppFactory::create();
$app->route('/', function (RequestInterface $request,
ResponseInterface $response, $next) {
$response->getBody()->write('Hello, world!');
return $response;
});
$app->run();
php -S 0.0.0.0:8080 -t
Instalação com Composer via
composer.json
{
"require": {
"zendframework/zend-expressive" : "*",
"zendframework/zend-servicemanager" : "*",
"zendframework/zend-expressive-
fastroute" : "*"
}
}
Se a rota não casar...
Cannot GET http://[URL DO PROJETO]]
Instalação com Composer via
terminal
composer require zendframework/zend-
expressive aura/router zendframework/zend-
servicemanager
Anatomia
Comparação com ZF2
Próximas funcionalidades
Um esqueleto de aplicação;
Criptografia de sessão;
Suporte a cache de HTTP;
Autenticação de usuário (via OAuth2 e/ou outros
mecanismos de autenticação).
Criando uma galeria de fotos com
ZendExpressive
Criando um novo projeto
composer create-project -s rc
zendframework/zend-expressive-skeleton
<project-directory>
Removendo o código desnecessário
rm public/favicon.ico
rm public/zf-logo.png
rm src/Action/*
rm test/Action/*
rm templates/app/*
rm templates/layout/*
Configuração do Container
<?php
return [
'dependencies' => [
'factories' => [
ZendExpressiveApplication::class =>
ZendExpressiveContainerApplicationFactory::class,
],
],
];
config/autoload/dependencies.global.php
Configuração das Rotas
<?php
return [
'dependencies' => [
'invokables' => [
ZendExpressiveRouterRouterInterface::class => ZendExpressiveRouterFastRouteRouter::class,
],
'factories' => [
AppActionIndexAction::class => AppActionIndexFactory::class,
]
],
'routes' => [
[
'name' => 'index',
'path' => '/',
'middleware' => AppActionIndexAction::class,
'allowed_methods' => ['GET'],
],
],
];
config/autoload/routes.global.php
Controlador
●
<?php
●
●
namespace AppAction;
●
●
use PsrHttpMessageServerRequestInterface;
●
use PsrHttpMessageResponseInterface;
●
use ZendExpressiveTemplateTemplateRendererInterface;
●
use ZendStratigilityMiddlewareInterface;
●
●
class IndexAction implements MiddlewareInterface
●
{
●
private $templateRenderer;
●
●
public function __construct(TemplateRendererInterface $templateRenderer)
●
{
●
$this->templateRenderer = $templateRenderer;
●
}
●
●
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
●
{
●
$html = $this->templateRenderer->render('app::index');
●
$response->getBody()->write($html);
●
return $response->withHeader('Content-Type', 'text/html');
●
}
●
}
●
src/Action/IndexAction.php
Fábrica
<?php
namespace AppAction;
use InteropContainerContainerInterface;
use ZendExpressiveTemplateTemplateRendererInterface;
class IndexFactory
{
public function __invoke(ContainerInterface $container)
{
$templateRenderer = $container->get(TemplateRendererInterface::class);
return new IndexAction($templateRenderer);
}
}
src/Action/IndexFactory.php
Templating
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title><?=$this->e($title);?></title>
</head>
<body>
<?=$this->section('content')?>
</body>
</html>
templates/layout/default.phtml
Caching
composer require doctrine/cache ^1.5
mkdir data/doctrine-cache
Caching
<?php
return [
'dependencies' => [
'factories' => [
// ...
DoctrineCommonCacheCache::class => AppDoctrineCacheFactory::class,
],
],
'application' => [
'cache_path' => 'data/doctrine-cache/',
],
];
config/autoload/dependencies.global.php
Caching
<?php
return [
'dependencies' => [
'factories' => [
AppMiddlewareCacheMiddleware::class => AppMiddlewareCacheFactory::class,
]
],
'middleware_pipeline' => [
'pre_routing' => [
[ 'middleware' => AppMiddlewareCacheMiddleware::class ],
],
'post_routing' => [
],
],
];
config/autoload/middleware-pipeline.global.php
Caching
<?php
namespace App;
use DoctrineCommonCacheFilesystemCache;
use InteropContainerContainerInterface;
use ZendServiceManagerExceptionServiceNotCreatedException;
class DoctrineCacheFactory
{
public function __invoke(ContainerInterface $container)
{
$config = $container->get('config');
if (!isset($config['application']['cache_path'])) {
throw new ServiceNotCreatedException('cache_path must be set in application configuration');
}
return new FilesystemCache($config['application']['cache_path']);
}
}
src/DoctrineCacheFactory.php
Caching
<?php
namespace AppMiddleware;
use DoctrineCommonCacheCache;
use InteropContainerContainerInterface;
class CacheFactory
{
public function __invoke(ContainerInterface $container)
{
$cache = $container->get(Cache::class);
return new CacheMiddleware($cache);
}
}
src/Middleware/CacheFactory.php
Caching
<?php
namespace AppMiddleware;
use DoctrineCommonCacheCache;
use PsrHttpMessageResponseInterface;
use PsrHttpMessageServerRequestInterface;
use ZendStratigilityMiddlewareInterface;
class CacheMiddleware implements MiddlewareInterface
{
private $cache;
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
src/Middleware/CacheMiddleware.php
Caching
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable
$next = null)
{
$cachedResponse = $this->getCachedResponse($request, $response);
if (null !== $cachedResponse) {
return $cachedResponse;
}
$response = $next($request, $response);
$this->cacheResponse($request, $response);
return $response;
}
src/Middleware/CacheMiddleware.php (cont.)
Caching
private function
getCacheKey(ServerRequestInterface $request)
{
return 'http-cache:'.$request->getUri()-
>getPath();
}
src/Middleware/CacheMiddleware.php (cont.)
Caching
private function getCachedResponse(ServerRequestInterface $request, ResponseInterface $response)
{
if ('GET' !== $request->getMethod()) {
return null;
}
$item = $this->cache->fetch($this->getCacheKey($request));
if (false === $item) {
return null;
}
$response->getBody()->write($item['body']);
foreach ($item['headers'] as $name => $value) {
$response = $response->withHeader($name, $value);
}
return $response;
}
src/Middleware/CacheMiddleware.php (cont.)
Caching
private function cacheResponse(ServerRequestInterface $request, ResponseInterface $response)
{
if ('GET' !== $request->getMethod() || !$response->hasHeader('Cache-Control')) {
return;
}
$cacheControl = $response->getHeader('Cache-Control');
$abortTokens = array('private', 'no-cache', 'no-store');
if (count(array_intersect($abortTokens, $cacheControl)) > 0) {
return;
}
src/Middleware/CacheMiddleware.php (cont.)
Caching
foreach ($cacheControl as $value) {
$parts = explode('=', $value);
if (count($parts) == 2 && 'max-age' === $parts[0]) {
$this->cache->save($this->getCacheKey($request), [
'body' => (string) $response->getBody(),
'headers' => $response->getHeaders(),
], intval($parts[1]));
return;
}
}
}
}
src/Middleware/CacheMiddleware.php (cont.)
Caching
rm -rf data/doctrine-cache/*
Limpeza de cache
Instalando um provedor de fotos
composer require
andrewcarteruk/astronomy-picture-of-
the-day ^0.1
NASA Astronomy Picture of the Day - API Wrapper
Instalando um provedor de fotos
<?php
return [
'dependencies' => [
'factories' => [
// ...
AndrewCarterUKAPODAPIInterface::class => AppAPIFactory::class,
],
],
'application' => [
// ...
'results_per_page' => 24,
'apod_api' => [
'store_path' => 'public/apod',
'base_url' => '/apod',
],
],
];
config/autoload/dependencies.global.php
Instalando um provedor de fotos
<?php
return [
'application' => [
'apod_api' => [
'api_key' => 'DEMO_KEY',
// DEMO_KEY might be good for a couple of requests
// Get your own here:
https://api.nasa.gov/index.html#live_example
],
],
];
config/autoload/dependencies.local.php
Instalando um provedor de fotos
<?php
return [
'dependencies' => [
// ...
'factories' => [
// ...
AppActionPictureListAction::class => AppActionPictureListFactory::class,
],
],
'routes' => [
// ...
[
'name' => 'picture-list',
'path' => '/picture-list[/{page:d+}]',
'middleware' => AppActionPictureListAction::class,
'allowed_methods' => ['GET'],
],
],
];
config/autoload/routes.global.php
Instalando um provedor de fotos
mkdir public/apod
Diretório de thumbnails
Instalando um provedor de fotos
<?php
namespace App;
use AndrewCarterUKAPODAPI;
use GuzzleHttpClient;
use InteropContainerContainerInterface;
use ZendServiceManagerExceptionServiceNotCreatedException;
class APIFactory
{
public function __invoke(ContainerInterface $container)
{
$config = $container->get('config');
if (!isset($config['application']['apod_api'])) {
throw new ServiceNotCreatedException('apod_api must be set in application configuration');
}
return new API(new Client, $config['application']['apod_api']);
}
}
src/APIFactory.php
Instalando um provedor de fotos
<?php
namespace AppAction;
use AndrewCarterUKAPODAPIInterface;
use InteropContainerContainerInterface;
use ZendServiceManagerExceptionServiceNotCreatedException;
class PictureListFactory
{
public function __invoke(ContainerInterface $container)
{
$apodApi = $container->get(APIInterface::class);
$config = $container->get('config');
if (!isset($config['application']['results_per_page'])) {
throw new ServiceNotCreatedException('results_per_page must be set in application configuration');
}
return new PictureListAction($apodApi, $config['application']['results_per_page']);
}
}
src/Action/PictureListFactory.php
Instalando um provedor de fotos
<?php
namespace AppAction;
use AndrewCarterUKAPODAPIInterface;
use PsrHttpMessageServerRequestInterface;
use PsrHttpMessageResponseInterface;
use ZendStratigilityMiddlewareInterface;
class PictureListAction implements MiddlewareInterface
{
private $apodApi;
private $resultsPerPage;
public function __construct(APIInterface $apodApi, $resultsPerPage)
{
$this->apodApi = $apodApi;
$this->resultsPerPage = $resultsPerPage;
}
src/Action/PictureListAction.php
Instalando um provedor de fotos
public function __invoke(ServerRequestInterface $request,
ResponseInterface $response, callable $out = null)
{
$page = intval($request->getAttribute('page')) ?: 0;
$pictures = $this->apodApi->getPage($page, $this->resultsPerPage);
$response->getBody()->write(json_encode($pictures));
return $response
// ->withHeader('Cache-Control', ['public', 'max-age=3600'])
->withHeader('Content-Type', 'application/json');
}
}
src/Action/PictureListAction.php (cont.)
Instalando um provedor de fotos
<?php
chdir(__DIR__.'/..');
include 'vendor/autoload.php';
$container = include 'config/container.php';
// Create a SIGINT handler that sets a shutdown flag
$shutdown = false;
declare(ticks = 1);
pcntl_signal(SIGINT, function () use (&$shutdown) {
$shutdown = true;
});
bin/update.php
Instalando um provedor de fotos
$newPictureHandler = function (array $picture) use (&$shutdown) {
echo 'Added: ' . $picture['title'] . PHP_EOL;
// If the shutdown flag has been set, die
if ($shutdown) {
die;
}
};
$errorHandler = function (Exception $exception) use (&$shutdown) {
echo (string) $exception . PHP_EOL;
// If the shutdown flag has been set, die
if ($shutdown) {
die;
}
};
$container->get(AndrewCarterUKAPODAPIInterface::class)->updateStore(20, $newPictureHandler, $errorHandler);
bin/update.php (cont.)
API Key NASA
● https://api.nasa.gov/index.html#live_example
php bin/update.php
Onde estará o ZF3?
Referência
● Zimuel, E. Pushing Boundaries: Zend
Framework 3. Disponível em
<http://zimuel.it/slides/phpday2015>
● Ikhsan, A. M. e O'Phinney, M. W. How to Build
a NASA Photo Gallery with Zend Expressive.
Disponível em <http://www.sitepoint.com/build-
nasa-photo-gallery-zend-expressive/>

Contenu connexe

Tendances

Conhecendo o Zend Framework
Conhecendo o Zend FrameworkConhecendo o Zend Framework
Conhecendo o Zend FrameworkJaime Neto
 
Zend Framework 1.11
Zend Framework 1.11Zend Framework 1.11
Zend Framework 1.11Cezar Souza
 
Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011Bruno Rocha
 
Criando API Rest no Zend Framework 2
Criando API Rest no Zend Framework 2Criando API Rest no Zend Framework 2
Criando API Rest no Zend Framework 2Rankest
 
Seu framework é melhor pra quê?
Seu framework é melhor pra quê?Seu framework é melhor pra quê?
Seu framework é melhor pra quê?Jaime Neto
 
Performance de verdade com Phalcon Framework
Performance de verdade com Phalcon FrameworkPerformance de verdade com Phalcon Framework
Performance de verdade com Phalcon FrameworkJaime Neto
 
PHP para aplicações Web de grande porte
PHP para aplicações Web  de grande portePHP para aplicações Web  de grande porte
PHP para aplicações Web de grande porteFelipe Ribeiro
 
Segurança em Aplicações Web com PHP
Segurança em Aplicações Web com PHPSegurança em Aplicações Web com PHP
Segurança em Aplicações Web com PHPGedvan Dias
 
Mini Curso Zend Framework
Mini Curso Zend FrameworkMini Curso Zend Framework
Mini Curso Zend FrameworkAdler Medrado
 
PHP Experience 2016 - [Palestra] Rumo à Certificação PHP
PHP Experience 2016 - [Palestra] Rumo à Certificação PHPPHP Experience 2016 - [Palestra] Rumo à Certificação PHP
PHP Experience 2016 - [Palestra] Rumo à Certificação PHPiMasters
 
Certificação Zend Framework
Certificação Zend FrameworkCertificação Zend Framework
Certificação Zend FrameworkJaime Neto
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com DjangoMarinho Brandão
 
ASP.Net Core FAQ
ASP.Net Core FAQASP.Net Core FAQ
ASP.Net Core FAQLuiz Duarte
 
PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...
PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...
PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...iMasters
 
Zend Framework 2 - Desenvolvimento Ágil Competente
Zend Framework 2 - Desenvolvimento Ágil CompetenteZend Framework 2 - Desenvolvimento Ágil Competente
Zend Framework 2 - Desenvolvimento Ágil CompetenteMichael Cardoso
 
Android chat app com Node.js
Android chat app com Node.jsAndroid chat app com Node.js
Android chat app com Node.jsLuiz Duarte
 
Django - Desenvolvimento web ágil com Python
Django - Desenvolvimento web ágil com PythonDjango - Desenvolvimento web ágil com Python
Django - Desenvolvimento web ágil com PythonIgor Sobreira
 
Javascript por debaixo dos panos
Javascript por debaixo dos panosJavascript por debaixo dos panos
Javascript por debaixo dos panosLaís Lima
 

Tendances (20)

Como fazer boas libs
Como fazer boas libs Como fazer boas libs
Como fazer boas libs
 
Conhecendo o Zend Framework
Conhecendo o Zend FrameworkConhecendo o Zend Framework
Conhecendo o Zend Framework
 
Zend Framework 1.11
Zend Framework 1.11Zend Framework 1.11
Zend Framework 1.11
 
Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011
 
Criando API Rest no Zend Framework 2
Criando API Rest no Zend Framework 2Criando API Rest no Zend Framework 2
Criando API Rest no Zend Framework 2
 
Seu framework é melhor pra quê?
Seu framework é melhor pra quê?Seu framework é melhor pra quê?
Seu framework é melhor pra quê?
 
Performance de verdade com Phalcon Framework
Performance de verdade com Phalcon FrameworkPerformance de verdade com Phalcon Framework
Performance de verdade com Phalcon Framework
 
PHP para aplicações Web de grande porte
PHP para aplicações Web  de grande portePHP para aplicações Web  de grande porte
PHP para aplicações Web de grande porte
 
Segurança em Aplicações Web com PHP
Segurança em Aplicações Web com PHPSegurança em Aplicações Web com PHP
Segurança em Aplicações Web com PHP
 
Mini Curso Zend Framework
Mini Curso Zend FrameworkMini Curso Zend Framework
Mini Curso Zend Framework
 
PHP Experience 2016 - [Palestra] Rumo à Certificação PHP
PHP Experience 2016 - [Palestra] Rumo à Certificação PHPPHP Experience 2016 - [Palestra] Rumo à Certificação PHP
PHP Experience 2016 - [Palestra] Rumo à Certificação PHP
 
Certificação Zend Framework
Certificação Zend FrameworkCertificação Zend Framework
Certificação Zend Framework
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com Django
 
ASP.Net Core FAQ
ASP.Net Core FAQASP.Net Core FAQ
ASP.Net Core FAQ
 
PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...
PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...
PHP Experience 2016 - [Palestra] Vagrant, LXC, Docker, etc: Entenda as difere...
 
Zend Framework 2 - Desenvolvimento Ágil Competente
Zend Framework 2 - Desenvolvimento Ágil CompetenteZend Framework 2 - Desenvolvimento Ágil Competente
Zend Framework 2 - Desenvolvimento Ágil Competente
 
Android chat app com Node.js
Android chat app com Node.jsAndroid chat app com Node.js
Android chat app com Node.js
 
Django - Desenvolvimento web ágil com Python
Django - Desenvolvimento web ágil com PythonDjango - Desenvolvimento web ágil com Python
Django - Desenvolvimento web ágil com Python
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Javascript por debaixo dos panos
Javascript por debaixo dos panosJavascript por debaixo dos panos
Javascript por debaixo dos panos
 

Similaire à O que esperar do Zend Framework 3: componentes, HTTP, PHP 7 e mais

Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Elton Minetto
 
Webservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHPWebservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHPFlávio Lisboa
 
Lampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 PalestraLampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 PalestraDavid O'Keefe
 
Minha aplicação Java vai pra nuvem. E agora?
Minha aplicação Java vai pra nuvem. E agora?Minha aplicação Java vai pra nuvem. E agora?
Minha aplicação Java vai pra nuvem. E agora?Felipe Mamud
 
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015  Porto Alegre - Interfaces ricas com Rails e React.JSTDC2015  Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JSRodrigo Urubatan
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Frameworkelliando dias
 
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...tdc-globalcode
 
Ligação do Flex a um backend LAMP usando AMFPHP
Ligação do Flex a um backend LAMP usando AMFPHPLigação do Flex a um backend LAMP usando AMFPHP
Ligação do Flex a um backend LAMP usando AMFPHPelliando dias
 
2290494 integrando-flex-com-php
2290494 integrando-flex-com-php2290494 integrando-flex-com-php
2290494 integrando-flex-com-phpBrenno Abreu
 
Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2PrinceGuru MS
 
O que esperar do Zend Framework 2
O que esperar do Zend Framework 2O que esperar do Zend Framework 2
O que esperar do Zend Framework 2Flávio Lisboa
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformanceFelipe Ribeiro
 
Alta Performance de Aplicações PHP com Nginx
Alta Performance de Aplicações PHP com NginxAlta Performance de Aplicações PHP com Nginx
Alta Performance de Aplicações PHP com NginxThiago Paes
 
PHP like a super hero
PHP like a super heroPHP like a super hero
PHP like a super heroElton Minetto
 
Construindo portlets para IBM WebSphere Portal – Parte 2
Construindo portlets para IBM WebSphere Portal – Parte 2Construindo portlets para IBM WebSphere Portal – Parte 2
Construindo portlets para IBM WebSphere Portal – Parte 2rodrigoareis
 
Aplicações com Tecnologias Web
Aplicações com Tecnologias WebAplicações com Tecnologias Web
Aplicações com Tecnologias WebRildo Pragana
 

Similaire à O que esperar do Zend Framework 3: componentes, HTTP, PHP 7 e mais (20)

Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2
 
Webservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHPWebservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHP
 
Lampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 PalestraLampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 Palestra
 
Minha aplicação Java vai pra nuvem. E agora?
Minha aplicação Java vai pra nuvem. E agora?Minha aplicação Java vai pra nuvem. E agora?
Minha aplicação Java vai pra nuvem. E agora?
 
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015  Porto Alegre - Interfaces ricas com Rails e React.JSTDC2015  Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Php FrameWARks - sem CakePHP
Php FrameWARks - sem CakePHPPhp FrameWARks - sem CakePHP
Php FrameWARks - sem CakePHP
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Framework
 
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
 
A Revolução dos Middlewares
A Revolução dos MiddlewaresA Revolução dos Middlewares
A Revolução dos Middlewares
 
Ligação do Flex a um backend LAMP usando AMFPHP
Ligação do Flex a um backend LAMP usando AMFPHPLigação do Flex a um backend LAMP usando AMFPHP
Ligação do Flex a um backend LAMP usando AMFPHP
 
2290494 integrando-flex-com-php
2290494 integrando-flex-com-php2290494 integrando-flex-com-php
2290494 integrando-flex-com-php
 
Python 08
Python 08Python 08
Python 08
 
Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2
 
O que esperar do Zend Framework 2
O que esperar do Zend Framework 2O que esperar do Zend Framework 2
O que esperar do Zend Framework 2
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta Performance
 
Alta Performance de Aplicações PHP com Nginx
Alta Performance de Aplicações PHP com NginxAlta Performance de Aplicações PHP com Nginx
Alta Performance de Aplicações PHP com Nginx
 
PHP like a super hero
PHP like a super heroPHP like a super hero
PHP like a super hero
 
Construindo portlets para IBM WebSphere Portal – Parte 2
Construindo portlets para IBM WebSphere Portal – Parte 2Construindo portlets para IBM WebSphere Portal – Parte 2
Construindo portlets para IBM WebSphere Portal – Parte 2
 
Aplicações com Tecnologias Web
Aplicações com Tecnologias WebAplicações com Tecnologias Web
Aplicações com Tecnologias Web
 

Plus de Flávio Lisboa

Criando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPCriando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPFlávio Lisboa
 
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaCooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaFlávio Lisboa
 
Aprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasAprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasFlávio Lisboa
 
Ciência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoCiência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoFlávio Lisboa
 
Turbinando microsserviços em PHP
Turbinando microsserviços em PHPTurbinando microsserviços em PHP
Turbinando microsserviços em PHPFlávio Lisboa
 
O que esperar do framework Laminas
O que esperar do framework LaminasO que esperar do framework Laminas
O que esperar do framework LaminasFlávio Lisboa
 
PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?Flávio Lisboa
 
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Flávio Lisboa
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHPFlávio Lisboa
 
Como se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoComo se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoFlávio Lisboa
 
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPA demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPFlávio Lisboa
 
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamComunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamFlávio Lisboa
 
Criação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosCriação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosFlávio Lisboa
 
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosEstudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosFlávio Lisboa
 
Arquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosArquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosFlávio Lisboa
 
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasSemeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasFlávio Lisboa
 
O que é programação de computadores
O que é programação de computadoresO que é programação de computadores
O que é programação de computadoresFlávio Lisboa
 
Economia em rede (comunidade)
Economia em rede (comunidade)Economia em rede (comunidade)
Economia em rede (comunidade)Flávio Lisboa
 
Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Flávio Lisboa
 

Plus de Flávio Lisboa (20)

Criando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPCriando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHP
 
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaCooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
 
Aprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasAprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com Laminas
 
Ciência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoCiência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com método
 
Turbinando microsserviços em PHP
Turbinando microsserviços em PHPTurbinando microsserviços em PHP
Turbinando microsserviços em PHP
 
O que esperar do framework Laminas
O que esperar do framework LaminasO que esperar do framework Laminas
O que esperar do framework Laminas
 
PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?
 
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHP
 
Como se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoComo se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundo
 
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPA demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
 
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamComunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
 
Criação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosCriação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dados
 
Amanhecer esmeralda
Amanhecer esmeraldaAmanhecer esmeralda
Amanhecer esmeralda
 
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosEstudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
 
Arquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosArquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviços
 
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasSemeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
 
O que é programação de computadores
O que é programação de computadoresO que é programação de computadores
O que é programação de computadores
 
Economia em rede (comunidade)
Economia em rede (comunidade)Economia em rede (comunidade)
Economia em rede (comunidade)
 
Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)
 

O que esperar do Zend Framework 3: componentes, HTTP, PHP 7 e mais

  • 1. O que esperar do Zend Framework 3 Flávio Gomes da Silva Lisboa www.fgsl.eti.br
  • 2. Quem sou eu? ● Bacharel em Ciência da Computação com pós-graduação em Aplicações Corporativas usando Orientação a Objetos e Tecnologia Java pela Universidade Tecnológica Federal do Paraná. Programador formado pelo Centro Estadual de Educação Tecnológica Paula Souza. ● Chefe do setor de adequação da solução e mobilidade do projeto Expresso 3 na Coordenação Estratégica de Ações Governamentais do Serviço Federal de Processamento de Dados (Serpro). ● Zend PHP Certified Engineer, Zend Framework Certified Engineer e Zend Framework 2 Certified Architect.
  • 5. E em breve... Zend Framework Componentes Poderosos para PHP 3ª edição Criando Aplicações PHP com Zend e ExtJS
  • 8. Sumário ● Componentes ● HTTP, PSR-7 e Middleware ● PHP 7 e PHP 5.5
  • 9. ZF3 ● Ênfase em componentes
  • 10. ZF3 ● Ênfase em componentes ● Foco em HTTP, via PSR-7 e middleware
  • 11. ZF3 ● Ênfase em componentes ● Foco em HTTP, via PSR-7 e middleware ● Otimizado para PHP 7, mas suporta PHP 5.5+
  • 12. ZF3 ● Ênfase em componentes ● Foco em HTTP, via PSR-7 e middleware ● Otimizado para PHP 7, mas suporta PHP 5.5+ ● Lançamento previsto para...
  • 14. ZF1: o passado ● Componentes eram desenvolvidos dentro do repositório do framework, e
  • 15. ZF1: o passado ● Componentes eram desenvolvidos dentro do repositório do framework, e ● Eram instaláveis somente com o framework inteiro.
  • 16. ZF2: o presente ● Componentes são desenvolvidos dentro do repositório do framework, e ● Podem ser instalados individualmente (Composer, GIT).
  • 17. ZF 2.5: o presente ● Não há mais pacotes de instalação. ● O repositório ZF depende dos componentes.
  • 18. Instale só o que vai usar { "require": { "zendframework/zend-authentication": "^2.5", "zendframework/zend-cache": "^2.5", "zendframework/zend-captcha": "^2.5", "etc": "*" } }
  • 20. Fácil manutenção ● Permite mais times com direitos de alterar código de componentes ● Permite um destino determinístico de repositórios
  • 21. Esqueletos específicos para casos de uso ● Entrega somente serviços? ● Precisa de desempenho? ● Precisa de tudo? Haverá um esqueleto para isso!
  • 22. HTTP, PSR-7 e Middleware
  • 23. HTTP é o fundamento da Web ● Um cliente envia uma requisição ● Um servidor devolve uma resposta
  • 24. Mensagens HTTP GET /path HTTP/1.1 Host: example.com Accept: application/json HTTP/1.1 200 OK Content-Type: application/json {"foo":"bar"} Requisição Resposta
  • 25. Frameworks modelam mensagens Mas cada framework faz isso diferente $method = $request->getMethod(); $method = $request->getRequestMethod(); $method = $request->method;
  • 26.
  • 27. Requisição $method = $request->getMethod(); $accept = $request->getHeader('Accept'); $path = $request->getUri()->getPath(); $controller = $request->getAttribute('controller');
  • 28. Resposta $response->getBody()->write('Hello world!'); $response = $response ->withStatus(200, 'OK') ->withHeader('Content-Type', 'text/plain');
  • 29. Middleware Entre a requisição e a resposta function (Request $request, Response $response) { // do some work return $response; // same, or a new instance. }
  • 30. Uma arquitetura de terceirização
  • 33. Pilhas ou Condutores $pipeline->pipe($middleware1); // always evaluate $pipeline->pipe('/path', $middleware2); // only if path matches $pipeline->pipe('/different/path', $middleware3); $response = $pipeline->run();
  • 34. Estilo Cebola class Outer { public $inner; public function __invoke($request, $response) { // do some work $response = ($this->inner)($request, $response); // do some work return $response; } } $response = $outer($request, $response);
  • 35. Estilo Lambda function (Request $request) { // do some work return $response; } $response = $middleware($request);
  • 36. Consumindo Middleware ZF permitirá despachar o seguinte middleware: … e controladores ZF serão middleware. /** * @return Response */ public function (Request $request, Response $response);
  • 37. Encapsulador de Middleware para ZF $middleware = new MvcMiddlewareWrapper( require 'config/application/config.php' ); class MvcMiddlewareWrapper { public function __invoke($request, $response) { $app = Application::init($this->config); return $app->dispatch($request, $response); } }
  • 38. Middleware como alternativa para tempo de execução ● Desempenho ● Experiência do desenvolvedor ● Reusabilidade entre frameworks
  • 39. Exemplo $app = new Middleware(); $app->pipe('/', $homepage); // Static! $app->pipe('/customer', $zf2Middleware); // ZF2! $app->pipe('/products', $zf1Middleware); // ZF1! $app->pipe('/api', $apigility); // Apigility! $app->pipe('/user', $userMiddleware); // 3rd party! $server->listen($app);
  • 40. PSR-7 e Middleware provêem... ● Caminhos para otimização de desempenho ● Interfaces para web mais simples ● Maior interoperabilidade e potencial reuso
  • 41. PHP 7 e PHP 5.5
  • 42. Atualização para o PHP 5.5 ● Conseguimos usar traits! ● Conseguimos usar a sintaxe curta de array! ● Conseguimos usar callable type hint! ● Conseguimos usar finally! ● Podemos usar a constante mágica ::class! ● Conseguimos usar generators! ● Conseguimos um PHP mais rápido, mais seguro!
  • 43. PHP 7 Impressionante melhoria de desempenho! Novo gerenciamento de estruturas de dados no motor do PHP Novas funcionalidades como declarações de tipo para argumento e retorno
  • 44. PHP 7 : Benchmark PHP 5.6 PHP 7 Uso de memória 428 MB 33 MB Tempo de execução 0.49 sec 0.06 sec $a = array(); for ($i = 0; $i < 1000000; $i++) { $a[$i] = array("hello"); } echo memory_get_usage(true);
  • 48. ZF3: Otimizado para PHP 7 Atualizar PHP provê melhor segurança, melhora o desempenho e permite melhorar o framework
  • 49. Certo, mas e onde está esse ZF3?
  • 50.
  • 51. Não existe Zend Framework 3
  • 53.
  • 54. Zend Expressive Expressive permite que você escreva aplicações middleware PSR-7 para a web. É um simples micro- framework construído no topo do Stratigility, fornecendo: ● Roteamento dinâmico; ● Injeção de dependência via interoperabilidade de containers; ● Templating; ● Manipulação de erros.
  • 55. Hello World (para index.php no web root) // In index.php use ZendExpressiveAppFactory; use PsrHttpMessageResponseInterface; use PsrHttpMessageRequestInterface; require 'vendor/autoload.php'; $app = AppFactory::create(); $app->route('/', function (RequestInterface $request, ResponseInterface $response, $next) { $response->getBody()->write('Hello, world!'); return $response; }); $app->run(); php -S 0.0.0.0:8080 -t
  • 56. Instalação com Composer via composer.json { "require": { "zendframework/zend-expressive" : "*", "zendframework/zend-servicemanager" : "*", "zendframework/zend-expressive- fastroute" : "*" } }
  • 57. Se a rota não casar... Cannot GET http://[URL DO PROJETO]]
  • 58. Instalação com Composer via terminal composer require zendframework/zend- expressive aura/router zendframework/zend- servicemanager
  • 61. Próximas funcionalidades Um esqueleto de aplicação; Criptografia de sessão; Suporte a cache de HTTP; Autenticação de usuário (via OAuth2 e/ou outros mecanismos de autenticação).
  • 62. Criando uma galeria de fotos com ZendExpressive
  • 63. Criando um novo projeto composer create-project -s rc zendframework/zend-expressive-skeleton <project-directory>
  • 64. Removendo o código desnecessário rm public/favicon.ico rm public/zf-logo.png rm src/Action/* rm test/Action/* rm templates/app/* rm templates/layout/*
  • 65. Configuração do Container <?php return [ 'dependencies' => [ 'factories' => [ ZendExpressiveApplication::class => ZendExpressiveContainerApplicationFactory::class, ], ], ]; config/autoload/dependencies.global.php
  • 66. Configuração das Rotas <?php return [ 'dependencies' => [ 'invokables' => [ ZendExpressiveRouterRouterInterface::class => ZendExpressiveRouterFastRouteRouter::class, ], 'factories' => [ AppActionIndexAction::class => AppActionIndexFactory::class, ] ], 'routes' => [ [ 'name' => 'index', 'path' => '/', 'middleware' => AppActionIndexAction::class, 'allowed_methods' => ['GET'], ], ], ]; config/autoload/routes.global.php
  • 67. Controlador ● <?php ● ● namespace AppAction; ● ● use PsrHttpMessageServerRequestInterface; ● use PsrHttpMessageResponseInterface; ● use ZendExpressiveTemplateTemplateRendererInterface; ● use ZendStratigilityMiddlewareInterface; ● ● class IndexAction implements MiddlewareInterface ● { ● private $templateRenderer; ● ● public function __construct(TemplateRendererInterface $templateRenderer) ● { ● $this->templateRenderer = $templateRenderer; ● } ● ● public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) ● { ● $html = $this->templateRenderer->render('app::index'); ● $response->getBody()->write($html); ● return $response->withHeader('Content-Type', 'text/html'); ● } ● } ● src/Action/IndexAction.php
  • 68. Fábrica <?php namespace AppAction; use InteropContainerContainerInterface; use ZendExpressiveTemplateTemplateRendererInterface; class IndexFactory { public function __invoke(ContainerInterface $container) { $templateRenderer = $container->get(TemplateRendererInterface::class); return new IndexAction($templateRenderer); } } src/Action/IndexFactory.php
  • 69. Templating <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title><?=$this->e($title);?></title> </head> <body> <?=$this->section('content')?> </body> </html> templates/layout/default.phtml
  • 70. Caching composer require doctrine/cache ^1.5 mkdir data/doctrine-cache
  • 71. Caching <?php return [ 'dependencies' => [ 'factories' => [ // ... DoctrineCommonCacheCache::class => AppDoctrineCacheFactory::class, ], ], 'application' => [ 'cache_path' => 'data/doctrine-cache/', ], ]; config/autoload/dependencies.global.php
  • 72. Caching <?php return [ 'dependencies' => [ 'factories' => [ AppMiddlewareCacheMiddleware::class => AppMiddlewareCacheFactory::class, ] ], 'middleware_pipeline' => [ 'pre_routing' => [ [ 'middleware' => AppMiddlewareCacheMiddleware::class ], ], 'post_routing' => [ ], ], ]; config/autoload/middleware-pipeline.global.php
  • 73. Caching <?php namespace App; use DoctrineCommonCacheFilesystemCache; use InteropContainerContainerInterface; use ZendServiceManagerExceptionServiceNotCreatedException; class DoctrineCacheFactory { public function __invoke(ContainerInterface $container) { $config = $container->get('config'); if (!isset($config['application']['cache_path'])) { throw new ServiceNotCreatedException('cache_path must be set in application configuration'); } return new FilesystemCache($config['application']['cache_path']); } } src/DoctrineCacheFactory.php
  • 74. Caching <?php namespace AppMiddleware; use DoctrineCommonCacheCache; use InteropContainerContainerInterface; class CacheFactory { public function __invoke(ContainerInterface $container) { $cache = $container->get(Cache::class); return new CacheMiddleware($cache); } } src/Middleware/CacheFactory.php
  • 75. Caching <?php namespace AppMiddleware; use DoctrineCommonCacheCache; use PsrHttpMessageResponseInterface; use PsrHttpMessageServerRequestInterface; use ZendStratigilityMiddlewareInterface; class CacheMiddleware implements MiddlewareInterface { private $cache; public function __construct(Cache $cache) { $this->cache = $cache; } src/Middleware/CacheMiddleware.php
  • 76. Caching public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) { $cachedResponse = $this->getCachedResponse($request, $response); if (null !== $cachedResponse) { return $cachedResponse; } $response = $next($request, $response); $this->cacheResponse($request, $response); return $response; } src/Middleware/CacheMiddleware.php (cont.)
  • 77. Caching private function getCacheKey(ServerRequestInterface $request) { return 'http-cache:'.$request->getUri()- >getPath(); } src/Middleware/CacheMiddleware.php (cont.)
  • 78. Caching private function getCachedResponse(ServerRequestInterface $request, ResponseInterface $response) { if ('GET' !== $request->getMethod()) { return null; } $item = $this->cache->fetch($this->getCacheKey($request)); if (false === $item) { return null; } $response->getBody()->write($item['body']); foreach ($item['headers'] as $name => $value) { $response = $response->withHeader($name, $value); } return $response; } src/Middleware/CacheMiddleware.php (cont.)
  • 79. Caching private function cacheResponse(ServerRequestInterface $request, ResponseInterface $response) { if ('GET' !== $request->getMethod() || !$response->hasHeader('Cache-Control')) { return; } $cacheControl = $response->getHeader('Cache-Control'); $abortTokens = array('private', 'no-cache', 'no-store'); if (count(array_intersect($abortTokens, $cacheControl)) > 0) { return; } src/Middleware/CacheMiddleware.php (cont.)
  • 80. Caching foreach ($cacheControl as $value) { $parts = explode('=', $value); if (count($parts) == 2 && 'max-age' === $parts[0]) { $this->cache->save($this->getCacheKey($request), [ 'body' => (string) $response->getBody(), 'headers' => $response->getHeaders(), ], intval($parts[1])); return; } } } } src/Middleware/CacheMiddleware.php (cont.)
  • 82. Instalando um provedor de fotos composer require andrewcarteruk/astronomy-picture-of- the-day ^0.1 NASA Astronomy Picture of the Day - API Wrapper
  • 83. Instalando um provedor de fotos <?php return [ 'dependencies' => [ 'factories' => [ // ... AndrewCarterUKAPODAPIInterface::class => AppAPIFactory::class, ], ], 'application' => [ // ... 'results_per_page' => 24, 'apod_api' => [ 'store_path' => 'public/apod', 'base_url' => '/apod', ], ], ]; config/autoload/dependencies.global.php
  • 84. Instalando um provedor de fotos <?php return [ 'application' => [ 'apod_api' => [ 'api_key' => 'DEMO_KEY', // DEMO_KEY might be good for a couple of requests // Get your own here: https://api.nasa.gov/index.html#live_example ], ], ]; config/autoload/dependencies.local.php
  • 85. Instalando um provedor de fotos <?php return [ 'dependencies' => [ // ... 'factories' => [ // ... AppActionPictureListAction::class => AppActionPictureListFactory::class, ], ], 'routes' => [ // ... [ 'name' => 'picture-list', 'path' => '/picture-list[/{page:d+}]', 'middleware' => AppActionPictureListAction::class, 'allowed_methods' => ['GET'], ], ], ]; config/autoload/routes.global.php
  • 86. Instalando um provedor de fotos mkdir public/apod Diretório de thumbnails
  • 87. Instalando um provedor de fotos <?php namespace App; use AndrewCarterUKAPODAPI; use GuzzleHttpClient; use InteropContainerContainerInterface; use ZendServiceManagerExceptionServiceNotCreatedException; class APIFactory { public function __invoke(ContainerInterface $container) { $config = $container->get('config'); if (!isset($config['application']['apod_api'])) { throw new ServiceNotCreatedException('apod_api must be set in application configuration'); } return new API(new Client, $config['application']['apod_api']); } } src/APIFactory.php
  • 88. Instalando um provedor de fotos <?php namespace AppAction; use AndrewCarterUKAPODAPIInterface; use InteropContainerContainerInterface; use ZendServiceManagerExceptionServiceNotCreatedException; class PictureListFactory { public function __invoke(ContainerInterface $container) { $apodApi = $container->get(APIInterface::class); $config = $container->get('config'); if (!isset($config['application']['results_per_page'])) { throw new ServiceNotCreatedException('results_per_page must be set in application configuration'); } return new PictureListAction($apodApi, $config['application']['results_per_page']); } } src/Action/PictureListFactory.php
  • 89. Instalando um provedor de fotos <?php namespace AppAction; use AndrewCarterUKAPODAPIInterface; use PsrHttpMessageServerRequestInterface; use PsrHttpMessageResponseInterface; use ZendStratigilityMiddlewareInterface; class PictureListAction implements MiddlewareInterface { private $apodApi; private $resultsPerPage; public function __construct(APIInterface $apodApi, $resultsPerPage) { $this->apodApi = $apodApi; $this->resultsPerPage = $resultsPerPage; } src/Action/PictureListAction.php
  • 90. Instalando um provedor de fotos public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $out = null) { $page = intval($request->getAttribute('page')) ?: 0; $pictures = $this->apodApi->getPage($page, $this->resultsPerPage); $response->getBody()->write(json_encode($pictures)); return $response // ->withHeader('Cache-Control', ['public', 'max-age=3600']) ->withHeader('Content-Type', 'application/json'); } } src/Action/PictureListAction.php (cont.)
  • 91. Instalando um provedor de fotos <?php chdir(__DIR__.'/..'); include 'vendor/autoload.php'; $container = include 'config/container.php'; // Create a SIGINT handler that sets a shutdown flag $shutdown = false; declare(ticks = 1); pcntl_signal(SIGINT, function () use (&$shutdown) { $shutdown = true; }); bin/update.php
  • 92. Instalando um provedor de fotos $newPictureHandler = function (array $picture) use (&$shutdown) { echo 'Added: ' . $picture['title'] . PHP_EOL; // If the shutdown flag has been set, die if ($shutdown) { die; } }; $errorHandler = function (Exception $exception) use (&$shutdown) { echo (string) $exception . PHP_EOL; // If the shutdown flag has been set, die if ($shutdown) { die; } }; $container->get(AndrewCarterUKAPODAPIInterface::class)->updateStore(20, $newPictureHandler, $errorHandler); bin/update.php (cont.)
  • 93. API Key NASA ● https://api.nasa.gov/index.html#live_example php bin/update.php
  • 95. Referência ● Zimuel, E. Pushing Boundaries: Zend Framework 3. Disponível em <http://zimuel.it/slides/phpday2015> ● Ikhsan, A. M. e O'Phinney, M. W. How to Build a NASA Photo Gallery with Zend Expressive. Disponível em <http://www.sitepoint.com/build- nasa-photo-gallery-zend-expressive/>