by Enrico Zimuel / @ezimuel
Senior Software Engineer
Zend Technologies, a Rogue Wave Company
|
We almost done, working on docs and the new web site.
The plan is to release the full ZF3 packages on June 2016.
A function that gets a request and generates a response
function ($request, $response) {
// manipulate $request to generate a $response
return $response;
}
// $request instanceOf Psr\Http\Message\RequestInterface
$method = $request->getMethod();
$accept = $request->getHeader('Accept');
$path = $request->getUri()->getPath();
$controller = $request->getAttribute('controller');
// $response instanceOf Psr\Http\Message\ResponseInterface
$response->getBody()->write('Hello world!');
$response = $response->withStatus(200, 'OK')
->withHeader('Content-Type', 'text/plain');
Use an additional callable during the invoke ($next)
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
class Middleware
{
public function __invoke(
Request $request,
Response $response,
callable $next = null
){
// do something before
if ($next) {
$next($request, $response);
}
// do something after
}
}
function ($request, $response, $next)
use Zend\Expressive\AppFactory;
chdir(dirname(__DIR__));
require 'vendor/autoload.php';
$app = AppFactory::create();
$app->get('/', function ($request, $response, $next) {
$response->getBody()->write('Hello, world!');
return $response;
});
$app->pipeRoutingMiddleware();
$app->pipeDispatchMiddleware();
$app->run();
// $app is an instance of Zend\Expressive\Application
// Executed in all the requests
$app->pipe($apiMiddleware);
$app->pipe('middleware service name');
// Pipe to a specific URL
$app->pipe('/api', $apiMiddleware);
$app->pipe('/api', 'middleware service name');
// Error handler
$app->pipeErrorHandler('error handler service name');
$app->pipeErrorHandler('/api', 'error handler service name');
use Zend\Expressive\AppFactory;
use Zend\ServiceManager\ServiceManager;
$container = new ServiceManager();
$container->setFactory('HelloWorld', function ($container) {
return function ($req, $res, $next) {
$res->write('Hello, world!');
return $res;
};
});
$app = AppFactory::create($container);
$app->get('/', 'HelloWorld');
We support container-interop
namespace Zend\Expressive\Router;
use Psr\Http\Message\ServerRequestInterface as Request;
interface RouterInterface
{
public function addRoute(Route $route);
public function match(Request $request);
public function generateUri($name, array $substitutions = []);
}
namespace Zend\Expressive\Template;
interface TemplateRendererInterface
{
public function render($name, $params = []);
public function addPath($path, $namespace = null);
public function getPaths();
public function addDefaultParam($templateName, $param, $value);
}
use Zend\Expressive\Application;
use Zend\Expressive\Plates\PlatesRenderer;
use Zend\Expressive\TemplatedErrorHandler;
$plates = new PlatesRenderer();
$plates->addPath(__DIR__ . '/templates/error', 'error');
$final = new TemplatedErrorHandler($plates, 'error::404', 'error::500');
$app = new Application($router, $container, $final);
$ composer create-project zendframework/zend-expressive-skeleton <path>
$ composer serve
Open your browser at http://localhost:8080
├── config │ └── autoload ├── data │ └── cache ├── public ├── src │ └── App │ └── Action ├── templates │ ├── app │ ├── error │ └── layout └── test
The application configuration files, including:
autoload/routes.global.php
return [
'dependencies' => [
'factories' => [
App\Action\FooAction::class => App\Action\FooFactory::class,
],
],
'routes' => [
[
'name' => 'home',
'path' => '/',
'middleware' => App\Action\FooAction::class,
'allowed_methods' => ['GET'],
]
],
];
public/index.php
// Delegate static file requests back to the PHP built-in webserver
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 \Interop\Container\ContainerInterface $container */
$container = require 'config/container.php';
/** @var \Zend\Expressive\Application $app */
$app = $container->get(\Zend\Expressive\Application::class);
$app->run();
config/container.php
use Zend\ServiceManager\Config;
use Zend\ServiceManager\ServiceManager;
// Load configuration
$config = require __DIR__ . '/config.php';
// Build container
$container = new ServiceManager();
(new Config($config['dependencies']))->configureServiceManager($container);
// Inject config
$container->setService('config', $config);
return $container;
src/App/Action/FooFactory.php
namespace App\Action;
use Interop\Container\ContainerInterface;
use Zend\Expressive\Template\TemplateRendererInterface;
class FooFactory
{
public function __invoke(ContainerInterface $container)
{
$template = ($container->has(TemplateRendererInterface::class))
? $container->get(TemplateRendererInterface::class)
: null;
return new FooAction($template);
}
}
src/App/Action/FooAction.php
namespace App\Action;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Expressive\Template\TemplateRendererInterface;
class FooAction
{
protected $template;
public function __construct(TemplateRendererInterface $template = null)
{
$this->template = $template;
}
public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response,
callable $next = null
) {
$data = [];
// get the data to print in the template
return new HtmlResponse($this->template->render('app::foo', $data));
}
}
Rate this talk at joind.in/talk/31a66
More info: zendframework.github.io/zend-expressive
Contact me: enrico [at] zend.com
Follow me: @ezimuel
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
I used reveal.js to make this presentation.