Top Banner
Rob Allen ~ @akrabat ~ November 2017
37

Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Aug 04, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

   

Rob Allen ~ @akrabat ~ November 2017

Page 2: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

The C in MVC

Rob Allen ~ @akrabat

Page 3: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Slim 3• Created by Josh Lockhart (phptherightway.com)• PSR-7 Request and Response objects• Middleware architecture• Built in DIC for configuration

Rob Allen ~ @akrabat

Page 4: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

HTTP Messages are the foundation

Rob Allen ~ @akrabat

Page 5: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Request & ResponseRequest:

{METHOD} {URI} HTTP/1.1

Header: value1,value2

Another-Header: value

Message body

Response:HTTP/1.1 {STATUS_CODE} {REASON_PHRASE}

Header: value

Some-Header: value

Message body

Rob Allen ~ @akrabat

Page 6: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

PSR 7: HTTP messagingOO interfaces to model HTTP

• RequestInterface (& ServerRequestInterface)• ResponseInterface

• UriInterface

• UploadedFileInterface

• StreamInterface

Rob Allen ~ @akrabat

Page 7: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

PSR 7: Example 1 /* Body implements Psr\Http\Message\StreamInterface */ 2 $body = new Body(fopen('php://temp', 'r+')); 3 $body->write('Hello World');

4

5 /* Response implements Psr\Http\Message\ResponseInterface */ 6 $response = new Response(); 7 $response = $response->withStatus(200)

8 ->withHeader('Content-Type', 'text/html')

9 ->withBody($body);

10

11

12 /* Note: with Slim's Response: */13 $response = $response->write("Hello world");

Rob Allen ~ @akrabat

Page 8: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Key feature 1: ImmutabilityRequest, Response, Uri & UploadFile are immutable1 $uri = new Uri('https://api.joind.in/v2.1/events');2 $uri2 = $uri->withQuery('?filter=upcoming');

3

4 $request = (new Request())5 ->withMethod('GET')

6 ->withUri($uri2)

7 ->withHeader('Accept', 'application/json')

8 ->withHeader('Authorization', 'Bearer 0873418d');

Rob Allen ~ @akrabat

Page 9: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Key feature 2: StreamsMessage bodies are streams1 $body = new Stream();2 $body->write('<p>Hello');

3 $body->write('World</p>');

4

5 $response = (new Response())6 ->withStatus(200, 'OK')

7 ->withHeader('Content-Type', 'application/header')

8 ->withBody($body);

Rob Allen ~ @akrabat

Page 10: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Let's talk about Slim

Rob Allen ~ @akrabat

Page 11: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Hello world<?php

require __DIR__ . '/../vendor/autoload.php';$app = new \Slim\App();

$app->get('/hi[/{name}]', function ($request, $response, $args) { $name = $args['name'] ?? 'world';

$response->write("Hello $name"); return $response;});

$app->run();

Rob Allen ~ @akrabat

Page 12: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Let's look at that route

$app->get('/hi[/{name}]', function ($request, $response, $args) { $name = $args['name'] ?? 'world';

$response->write("Hello $name"); return $response;});

Rob Allen ~ @akrabat

Page 13: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Let's look at that route

$app->get('/hi[/{name}]', function ($request, $response, $args) { $name = $args['name'] ?? 'world';

$response->write("Hello $name"); return $response;});

Rob Allen ~ @akrabat

Page 14: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Let's look at that route

$app->get('/hi[/{name}]', function ($request, $response, $args) { $name = $args['name'] ?? 'world';

$response->write("Hello $name"); return $response;});

Rob Allen ~ @akrabat

Page 15: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Middleware

Rob Allen ~ @akrabat

Page 16: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

MiddlewareMiddleware is code that exists between the request and response,and which can take the incoming request, perform actions basedon it, and either complete the response or pass delegation on tothe next middleware in the queue.

Matthew Weier O'Phinney

Rob Allen ~ @akrabat

Page 17: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Middleware

Rob Allen ~ @akrabat

Page 18: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Application middleware$timer = function ($request, $response, $next) { // before $start = microtime(true);

// call next middleware $response = $next($request, $response);

// after $taken = microtime(true) - $start; $response->write("<!-- Time taken: $taken -->");

return $response;}

$app->add($timer);

Rob Allen ~ @akrabat

Page 19: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Data transfer between middlewareclass IpAddressMiddleware{

public function __invoke($request, $response, $next) {

$ipAddress = $this->determineClientIpAddress($request);

$request = $request->withAttribute('ip_address', $ipAddress);

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

private function determineClientIpAddress($request) { // ... }

}

Rob Allen ~ @akrabat

Page 20: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Data transfer between middlewareclass GateKeeperMiddleware{

public function __invoke($request, $response, $next) {

$ipAddress = $request->getAttribute('ip_address');

if (!in_array($ipAddress, $this->allowedIpAddresses)) { return $response->withStatus(403); }

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

}

Rob Allen ~ @akrabat

Page 21: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Route middlewareDo stuff before or after this action!$app->get('/hi/{name}', function (...) {...}) ->add(function ($request, $response, $next) {

// before: sanitise route parameter $name = strip_tags($request->getAttribute('name'));

$request = $request->withAttribute('name', $name);

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

Rob Allen ~ @akrabat

Page 22: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Leverage middlewareApplication level:

• Authentication• Navigation• Session

Route level:

• Access control• Validation

Rob Allen ~ @akrabat

Page 23: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Slim ExtrasProvided separately from Slim 3Add via Composer

• slim/slim-httpcache - Cache-Control/Etag support• slim/slim-csrf - CSRF protection• slim/slim-flash - Transient messages• slim/twig-view - Twig template rendering• slim/php-view - PHP view template rendering

Rob Allen ~ @akrabat

Page 24: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Flash messages: Store$app->post('/blog/edit', function ($request, $response, $args) {

// save data to database ...

// Set flash message for next request $this->flash->addMessage('result', 'Post updated');

// Redirect return $response->withStatus(302) ->withHeader('Location', '/blog/list');

});

Rob Allen ~ @akrabat

Page 25: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Flash messages: Retrieve$app->get('/blog/list', function ($request, $response) {

// get $list of blogs ...

// Get message $message = $this->flash->getFirstMessage('result');

// Render page with Twig $html = $this->twig->fetch('blog.list.twig', [

'message' => $message,

'list' => $list,

]);

return $response->write($html);});

Rob Allen ~ @akrabat

Page 26: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Thoughts on organisingyour application

Rob Allen ~ @akrabat

Page 27: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Directory layoutChoose your own file organisation. This is mine./

├── app/

├── cache/

├── public/

│   ├── css/

│   ├── js/

│   └── index.php

├── vendor/

├── composer.json

└── composer.lock

Rob Allen ~ @akrabat

Page 28: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

app holds my codeapp/

├── src/

│   ├── App/

│   ├── Photos/

│   │   ├── FlickrService.php

│   │   └── Photo.php

├── templates/

│   ├── layout.twig

│   └── app/

│   └── home/

│   └── list.twig

├── dependencies.php

├── middleware.php

├── routes.php

└── settings.php

Rob Allen ~ @akrabat

Page 29: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Keep index.php clean// Prepare app$settings = require __DIR__ . '/../app/settings.php';$app = new \Slim\App($settings);

// Register dependencies with the DICrequire __DIR__ . '/../app/src/dependencies.php';

// Register middlewarerequire __DIR__ . '/../app/src/middleware.php';

// Register routesrequire __DIR__ . '/../app/src/routes.php';

// Run app$app->run();

Rob Allen ~ @akrabat

Page 30: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Configuration<?php

// settings.phpreturn [ // app specific 'flickr' => [

],

'db' => [

],

// view 'view' => [

],

];

Rob Allen ~ @akrabat

Page 31: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

DI is your friend// dependencies.php

// Register FlickrService into DIC$container = $app->getConatiner();

$container['FlickrService'] = function ($c) {

$key = $c['settings']['flickr']['key'];

$secret = $c['settings']['flickr']['secret'];

return new Photos\FlickrService($key, $secret);};

Rob Allen ~ @akrabat

Page 32: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

All routes in a single file// routes.php$app->get('/list', 'Photos\PhotosController:list');

$app->post('/upload', 'Photos\PhotosController:upload');

$app->get('/{id:\d+}', 'Photos\PhotosController:view');

Rob Allen ~ @akrabat

Page 33: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Register your controller with DIC// dependencies.php$container = $app->getContainer();

$container['Photos\PhotosController'] = function ($c) { $flickr = $c['FlickrService'];

$view = $c['view'];

return new Photos\PhotosController($flickr, $view);};

Rob Allen ~ @akrabat

Page 34: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Controllernamespace Photos;

final class PhotosController{

private $flickr; private $view;

public function __construct($flickr, $view) {

$this->flickr = $flickr;

$this->view = $view;

}

Rob Allen ~ @akrabat

Page 35: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Controller (cont) // action method public function list($request, $response) {

$keyword = $request->getParam('keyword');

$list = $this->flickr->search($keyword);

$body = $this->view->fetch('list.twig', [

'keyword' => $keyword,

'list' => $list,

]);

return $response->write($body); }

}

Rob Allen ~ @akrabat

Page 36: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Resources• http://www.slimframework.com/docs• https://github.com/slimphp/Slim• http://akrabat.com/category/slim-framework/• Slack: https://slimphp-slack-invite.herokuapp.com• Forum: http://discourse.slimframework.com• IRC: #slimphp on Freenode

Rob Allen ~ @akrabat

Page 37: Rob Allen ~ @akrabat ~ November 2017 · Slim 3 • Created by Josh Lockhart (phptherightway.com) • PSR-7 Request and Response objects • Middleware architecture • Built in DIC

Thank you!https://joind.in/talk/4dbf6

Rob Allen - http://akrabat.com - @akrabat

Rob Allen ~ @akrabat