http & middleware - akrabat.com€¦ · slim. created by josh lockhart (phptherightway.com) •...
TRANSCRIPT
![Page 1: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/1.jpg)
HTTP & MiddlewareRob Allen
November 2018
![Page 2: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/2.jpg)
Slim: The C in MVC
Rob Allen ~ @akrabat
![Page 3: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/3.jpg)
SlimCreated by Josh Lockhart (phptherightway.com)• PSR-2 coding style• PSR-4 autoloading• PSR-7 Request and Response objects• PSR-11 container support• Middleware architecture (PSR-15 upcoming)
Rob Allen ~ @akrabat
![Page 4: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/4.jpg)
HTTP messages
Rob Allen ~ @akrabat
![Page 5: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/5.jpg)
HTTP messages
Rob Allen ~ @akrabat
![Page 6: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/6.jpg)
RequestGET / HTTP/1.1Host: akrabat.comUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:63.0) Gecko/20100101 Firefox/63.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-GB,en;q=0.5Accept-Encoding: gzip, deflate, brConnection: keep-aliveIf-Modified-Since: Mon, 04 Nov 2018 16:21:02 GMTCache-Control: max-age=0
Rob Allen ~ @akrabat
![Page 7: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/7.jpg)
ResponseHTTP/1.1 200 OKServer: nginx/1.7.6Date: Mon, 04 Nov 2018 16:27:06 GMTContent-Type: text/html; charset=UTF-8Content-Length: 16091Connection: keep-aliveKeep-Alive: timeout=65Vary: Accept-Encoding, CookieCache-Control: max-age=3, must-revalidateContent-Encoding: gzipLast-Modified: Mon, 04 Apr 2016 16:21:02 GMTStrict-Transport-Security: max-age=15768000
<!DOCTYPE html><head>
Rob Allen ~ @akrabat
![Page 8: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/8.jpg)
How do we do this in PHP?Request:• $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES• apache_request_headers() / getallheaders()• php://input
Rob Allen ~ @akrabat
![Page 9: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/9.jpg)
How do we do this in PHP?Response:• header()• http_response_code()• header_list() / headers_sent()• echo (& ob_*() family)
Rob Allen ~ @akrabat
![Page 10: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/10.jpg)
How do we do this in PHP?URI:scheme://username:password@hostname:port/path?arg=value#anchor
• parse_url()• parse_str()• http_build_query()
Rob Allen ~ @akrabat
![Page 11: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/11.jpg)
PSR 7: HTTP messaging• Provides for a uniform access to HTTP messages• A set of interfaces for requests and responses• Created by Framework Interoperability Group
Rob Allen ~ @akrabat
![Page 12: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/12.jpg)
It's just a set of interfaces
Rob Allen ~ @akrabat
![Page 13: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/13.jpg)
RequestInterface• Protocol version• HTTP method• URI• Headers• Body
Rob Allen ~ @akrabat
![Page 14: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/14.jpg)
ServerRequestInterfaceIn addition to RequestInterface:• Server parameters• Query string arguments• Deserialised body• Uploaded Files• Attributes
Rob Allen ~ @akrabat
![Page 15: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/15.jpg)
Response• Protocol version• Status code (& reason phrase)• Headers• Body
Rob Allen ~ @akrabat
![Page 16: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/16.jpg)
Two key things aboutPSR-7
Rob Allen ~ @akrabat
![Page 17: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/17.jpg)
Firstly: Messages and URIsare IMMUTABLE!
Rob Allen ~ @akrabat
![Page 18: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/18.jpg)
ImmutabilityRequest, ServerRequest, Response & Uri are immutable$uri = new Uri('https://api.joind.in/v2.1/events');$uri2 = $uri->withQuery('?filter=upcoming');$uri3 = $uri->withQuery('?filter=cfp');
Rob Allen ~ @akrabat
![Page 19: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/19.jpg)
ImmutabilityRequest, ServerRequest, Response & Uri are immutable$uri = new Uri('https://api.joind.in/v2.1/events');$uri2 = $uri->withQuery('?filter=upcoming');$uri3 = $uri->withQuery('?filter=cfp');
public function withQuery($query){ $clone = clone $this; $clone->query = $this->filterQuery($query); return $clone;}
Rob Allen ~ @akrabat
![Page 20: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/20.jpg)
Common mistake$response = new Response();$response->withStatus(302);$response->withHeader('Location', 'http://example.com');
return $response;
Rob Allen ~ @akrabat
![Page 21: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/21.jpg)
What you meant!$response = new Response();$response = $response->withStatus(302);$response = $response->withHeader('Location', 'http://example.com');
// or
$response = new Response();$response = $response->withStatus(302) ->withHeader('Location', 'http://example.com');
Rob Allen ~ @akrabat
![Page 22: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/22.jpg)
HeadersReading from the message:$request->hasHeader('Accept'); // boolean$request->getHeader('Accept'); // array$request->getHeaderLine('Accept'); // string
Updating the message:$response = $response->withHeader('Accept', 'application/xml');$response = $response->withAddedHeader('Accept', 'text/xml');$response = $response->withoutHeader('Location');
Rob Allen ~ @akrabat
![Page 23: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/23.jpg)
Secondly: Message bodiesare STREAMS
Rob Allen ~ @akrabat
![Page 24: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/24.jpg)
StreamsAllows for very large message bodies in a memory efficientmanner$largeFile = __DIR__ . '/brand_guidelines.ppt';
return (new Response()) ->withHeader('Content-Type', 'application/vnd.ms-powerpoint') ->withHeader('Content-Length', (string) filesize($largeFile)) ->withBody(new Stream($largeFile));
Rob Allen ~ @akrabat
![Page 25: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/25.jpg)
Handling stringsFor strings, use the php:://temp stream: $response = $response->withBody(new Stream('php://temp')); $response->getBody()->write('Hello world!');
Rob Allen ~ @akrabat
![Page 26: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/26.jpg)
Mutable!$body->write('Hello');$body->write(' World!');
$response = (new Response()) ->withStatus(200, 'OK') ->withHeader('Content-Type', 'application/html') ->withBody($body);
Mitigate:
Use read-only streams for server requests and client responses
Rob Allen ~ @akrabat
![Page 27: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/27.jpg)
ServerRequest AttributesAllow passing of data from one component to the next// component 1function findCountry($request) { $country = $this->geoLocate($request); $request = $request->withAttribute('country', $country); return $request;}
// In an action methodfunction listAction($request, $response, $args) { $country = $request->getAttribute('country'); // do something now that we know the country}
Rob Allen ~ @akrabat
![Page 28: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/28.jpg)
MiddlewareTurns a request in to a response
Rob Allen ~ @akrabat
![Page 29: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/29.jpg)
Middleware
Rob Allen ~ @akrabat
![Page 30: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/30.jpg)
This is not new• NodeJS: Connect• Python: WSGI• Ruby: Rack• PHP: StackPHP, Slim
Rob Allen ~ @akrabat
![Page 31: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/31.jpg)
PSR-7 Signature (by convention) function ( ServerRequestInterface $request, ResponseInterface $response, callable $next ) : ResponseInterface;
Rob Allen ~ @akrabat
![Page 32: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/32.jpg)
PSR-7 Signature (by convention) function ( ServerRequestInterface $request, ResponseInterface $response, callable $next ) : ResponseInterface;
Rob Allen ~ @akrabat
![Page 33: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/33.jpg)
PSR-7 Signature (by convention) function ( ServerRequestInterface $request, ResponseInterface $response, callable $next ) : ResponseInterface;
Rob Allen ~ @akrabat
![Page 34: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/34.jpg)
PSR-7 Signature (by convention) function ( ServerRequestInterface $request, ResponseInterface $response, callable $next ) : ResponseInterface;
Rob Allen ~ @akrabat
![Page 35: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/35.jpg)
PSR-7 Signature (by convention) function ( ServerRequestInterface $request, ResponseInterface $response, callable $next ) : ResponseInterface;
Rob Allen ~ @akrabat
![Page 36: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/36.jpg)
PSR-7 Middlewarefunction (ServerRequestInterface $request, ResponseInterface $response, callable $next) : ResponseInterface{ // do something before
// call down the chain to the next middleware if ($next) { $response = $next($request, $response); }
// do something with $response after
return $response;}
Rob Allen ~ @akrabat
![Page 37: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/37.jpg)
PSR-7 Middlewarefunction (ServerRequestInterface $request, ResponseInterface $response, callable $next) : ResponseInterface{ // do something before
// call down the chain to the next middleware if ($next) { $response = $next($request, $response); }
// do something with $response after
return $response;}
Rob Allen ~ @akrabat
![Page 38: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/38.jpg)
PSR-7 Middlewarefunction (ServerRequestInterface $request, ResponseInterface $response, callable $next) : ResponseInterface{ // do something before
// call down the chain to the next middleware if ($next) { $response = $next($request, $response); }
// do something with $response after
return $response;}
Rob Allen ~ @akrabat
![Page 39: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/39.jpg)
PSR-7 Middlewarefunction (ServerRequestInterface $request, ResponseInterface $response, callable $next) : ResponseInterface{ // do something before
// call down the chain to the next middleware if ($next) { $response = $next($request, $response); }
// do something with $response after
return $response;}
Rob Allen ~ @akrabat
![Page 40: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/40.jpg)
PSR-7 Middlewarefunction (ServerRequestInterface $request, ResponseInterface $response, callable $next) : ResponseInterface{ // do something before
// call down the chain to the next middleware if ($next) { $response = $next($request, $response); }
// do something with $response after
return $response;}
Rob Allen ~ @akrabat
![Page 41: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/41.jpg)
What can you do with Middleware?Session CORS CSRFLogging Firewall Debug barAuthentication Throttling Error handlingHTTP cache Honeypot ValidationCSP etc...
Rob Allen ~ @akrabat
![Page 42: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/42.jpg)
Middleware dispatching$app = new Slim\App();
$app->add($mw1);$app->add(SomeMiddleware::class);$app->add('MoreMiddleware');$app->add([$instance, 'methodName']);$app->add(function ($request, $response, $next) { return $next($request, $response);});
$response = $app->run();
Rob Allen ~ @akrabat
![Page 43: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/43.jpg)
Data transfer between middlewareAttributes allow passing of data from one middleware to the nextclass IpAddress{ public function __invoke($request, $response, $next) { $ipAddress = $this->determineClientIpAddress($request); $request = $request->withAttribute('ip_address', $ipAddress); return $response = $next($request, $response); }
// full source: github.com/akrabat/ip-address-middleware}
Rob Allen ~ @akrabat
![Page 44: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/44.jpg)
Data transfer between middlewareAttributes allow passing of data from one middleware to the nextclass IpAddressMiddleware{ public function __invoke($request, $response, $next) { $ipAddress = $this->determineClientIpAddress($request); $request = $request->withAttribute('ip_address', $ipAddress); return $response = $next($request, $response); }
// full source: github.com/akrabat/ip-address-middleware}
Rob Allen ~ @akrabat
![Page 45: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/45.jpg)
Data transfer between middlewareAttributes allow passing of data from one middleware to the nextclass IpAddressMiddleware{ public function __invoke($request, $response, $next) { $ipAddress = $this->determineClientIpAddress($request); $request = $request->withAttribute('ip_address', $ipAddress); return $response = $next($request, $response); }
// full source: github.com/akrabat/ip-address-middleware}
Rob Allen ~ @akrabat
![Page 46: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/46.jpg)
Data transfer between middlewareAttributes allow passing of data from one middleware to the nextclass IpAddressMiddleware{ public function __invoke($request, $response, $next) { $ipAddress = $this->determineClientIpAddress($request); $request = $request->withAttribute('ip_address', $ipAddress); return $response = $next($request, $response); }
// full source: github.com/akrabat/ip-address-middleware}
Rob Allen ~ @akrabat
![Page 47: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/47.jpg)
Data transfer between middlewareAttributes allow passing of data from one middleware to the nextclass IpAddressMiddleware{ public function __invoke($request, $response, $next) { $ipAddress = $this->determineClientIpAddress($request); $request = $request->withAttribute('ip_address', $ipAddress); return $response = $next($request, $response); }
// full source: github.com/akrabat/ip-address-middleware}
Rob Allen ~ @akrabat
![Page 48: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/48.jpg)
Data transfer between middlewareRead the attributeclass GuardMiddleware{ protected $allowedIps = [10.0.0.1, 192.168.0.1]
public function __invoke($request, $response, $next) { $ipAddress = $request->getAttribute('ip_address'); if (!in_array($ipAddress, $this->allowedIps)) { return $response->withStatus(401); } return $next($request, $response); }}
Rob Allen ~ @akrabat
![Page 49: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/49.jpg)
Data transfer between middlewareRead the attributeclass GuardMiddleware{ protected $allowedIps = [10.0.0.1, 192.168.0.1]
public function __invoke($request, $response, $next) { $ipAddress = $request->getAttribute('ip_address'); if (!in_array($ipAddress, $this->allowedIps)) { return $response->withStatus(401); } return $next($request, $response); }}
Rob Allen ~ @akrabat
![Page 50: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/50.jpg)
Data transfer between middlewareRead the attributeclass GuardMiddleware{ protected $allowedIps = [10.0.0.1, 192.168.0.1]
public function __invoke($request, $response, $next) { $ipAddress = $request->getAttribute('ip_address'); if (!in_array($ipAddress, $this->allowedIps)) { return $response->withStatus(401); } return $next($request, $response); }}
Rob Allen ~ @akrabat
![Page 51: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/51.jpg)
Data transfer between middlewareRead the attributeclass GuardMiddleware{ protected $allowedIps = [10.0.0.1, 192.168.0.1]
public function __invoke($request, $response, $next) { $ipAddress = $request->getAttribute('ip_address'); if (!in_array($ipAddress, $this->allowedIps)) { return $response->withStatus(401); } return $next($request, $response); }}
Rob Allen ~ @akrabat
![Page 52: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/52.jpg)
Data transfer between middlewareRead the attributeclass GuardMiddleware{ protected $allowedIps = [10.0.0.1, 192.168.0.1]
public function __invoke($request, $response, $next) { $ipAddress = $request->getAttribute('ip_address'); if (!in_array($ipAddress, $this->allowedIps)) { return $response->withStatus(401); } return $next($request, $response); }}
Rob Allen ~ @akrabat
![Page 53: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/53.jpg)
PSR-15Two Interfaces from the Framework Interoperability Group:
• Psr\Http\Server\MiddlewareInterface• Psr\Http\Server\RequestHandlerInterface
Rob Allen ~ @akrabat
![Page 54: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/54.jpg)
PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) : ResponseInterface;}
Rob Allen ~ @akrabat
![Page 55: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/55.jpg)
PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) : ResponseInterface;}
Rob Allen ~ @akrabat
![Page 56: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/56.jpg)
PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) : ResponseInterface;}
Rob Allen ~ @akrabat
![Page 57: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/57.jpg)
PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) : ResponseInterface;}
Rob Allen ~ @akrabat
![Page 58: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/58.jpg)
PSR-15 MiddlewareInterfacenamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) : ResponseInterface;}
Rob Allen ~ @akrabat
![Page 59: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/59.jpg)
Structure of PSR-15 middlewareclass TimerMiddleware implements MiddlewareInterface{ public function process($request, $handler) { $start = microtime(true);
$response = $handler->handle($request);
$taken = microtime(true) - $start; $response->getBody()->write("<!-- Time: $taken -->");
return $response; }}
Rob Allen ~ @akrabat
![Page 60: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/60.jpg)
Structure of PSR-15 middlewareclass TimerMiddleware implements MiddlewareInterface{ public function process($request, $handler) { $start = microtime(true);
$response = $handler->handle($request);
$taken = microtime(true) - $start; $response->getBody()->write("<!-- Time: $taken -->");
return $response; }}
Rob Allen ~ @akrabat
![Page 61: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/61.jpg)
Structure of PSR-15 middlewareclass TimerMiddleware implements MiddlewareInterface{ public function process($request, $handler) { $start = microtime(true);
$response = $handler->handle($request);
$taken = microtime(true) - $start; $response->getBody()->write("<!-- Time: $taken -->");
return $response; }}
Rob Allen ~ @akrabat
![Page 62: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/62.jpg)
Structure of PSR-15 middlewareclass TimerMiddleware implements MiddlewareInterface{ public function process($request, $handler) { $start = microtime(true);
$response = $handler->handle($request);
$taken = microtime(true) - $start; $response->getBody()->write("<!-- Time: $taken -->");
return $response; }}
Rob Allen ~ @akrabat
![Page 63: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/63.jpg)
Structure of PSR-15 middlewareclass TimerMiddleware implements MiddlewareInterface{ public function process($request, $handler) { $start = microtime(true);
$response = $handler->handle($request);
$taken = microtime(true) - $start; $response->getBody()->write("<!-- Time: $taken -->");
return $response; }}
Rob Allen ~ @akrabat
![Page 64: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/64.jpg)
Structure of PSR-15 middlewareclass TimerMiddleware implements MiddlewareInterface{ public function process($request, $handler) { $start = microtime(true);
$response = $handler->handle($request);
$taken = microtime(true) - $start; $response->getBody()->write("<!-- Time: $taken -->");
return $response; }}
Rob Allen ~ @akrabat
![Page 65: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/65.jpg)
PSR-15 RequestHandlernamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface RequestHandlerInterface{ public function handle( ServerRequestInterface $request ): ResponseInterface;}
Rob Allen ~ @akrabat
![Page 66: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/66.jpg)
PSR-15 RequestHandlernamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface RequestHandlerInterface{ public function handle( ServerRequestInterface $request ): ResponseInterface;}
Rob Allen ~ @akrabat
![Page 67: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/67.jpg)
PSR-15 RequestHandlernamespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;
interface RequestHandlerInterface{ public function handle( ServerRequestInterface $request ): ResponseInterface;}
Rob Allen ~ @akrabat
![Page 68: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/68.jpg)
A typical PSR-15 RequestHandlernamespace App\Handler;
// (use statements here)
class HomePageHandler implements RequestHandlerInterface{ public function handle(ServerRequestInterface $request) : ResponseInterface { return new HtmlResponse( '<p>Hello World</p>' ); }}
Rob Allen ~ @akrabat
![Page 69: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/69.jpg)
A typical PSR-15 RequestHandlernamespace App\Handler;
// (use statements here)
class HomePageHandler implements RequestHandlerInterface{ public function handle(ServerRequestInterface $request) : ResponseInterface { return new HtmlResponse( '<p>Hello World</p>' ); }}
Rob Allen ~ @akrabat
![Page 70: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/70.jpg)
A typical PSR-15 RequestHandlernamespace App\Handler;
// (use statements here)
class HomePageHandler implements RequestHandlerInterface{ public function handle(ServerRequestInterface $request) : ResponseInterface { return new HtmlResponse( '<p>Hello World</p>' ); }}
Rob Allen ~ @akrabat
![Page 71: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/71.jpg)
Frameworks
Rob Allen ~ @akrabat
![Page 72: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/72.jpg)
Zend Expressive: PSR-15$app = new Zend\Expressive\Application(/* ... */);
// add middleware$app->pipe(ErrorHandler::class);$app->pipe(RouteMiddleware::class);$app->pipe(IpAddress::class);$app->pipe(DispatchMiddleware::class);
// add routes$app->get('/', App\Handler\HomePageHandler::class);$app->get('/api/ping', App\Handler\PingHandler::class);
// run$app->run();
Rob Allen ~ @akrabat
![Page 73: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/73.jpg)
Slim Framework: PSR-7$app = new Slim\App();
// add middleware$app->add(IpAddress::class);
// add routes$app->get('/', App\Action\HomePageAction::class);$app->get('/api/ping', 'App\Controller\ApiController:pingAction');
// run$app->run();
Rob Allen ~ @akrabat
![Page 74: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/74.jpg)
Middleware componentsSearch on Packagist• https://packagist.org/search/?q=psr-7%20middleware• https://packagist.org/search/?query=psr-15%20middleware
Ones I use:• akrabat: ip-address-middleware & proxy-detection-middleware• tuupola: cors-middleware, slim-jwt-auth & slim-basic-auth• franzl: whoops-middleware• oscarotero: psr7-middlewares & psr15-middlewares
Rob Allen ~ @akrabat
![Page 75: HTTP & Middleware - akrabat.com€¦ · Slim. Created by Josh Lockhart (phptherightway.com) • PSR-2 coding style • PSR-4 autoloading • PSR-7 Request and Response objects •](https://reader030.vdocument.in/reader030/viewer/2022041018/5ecccfb7c221095fc21e2c48/html5/thumbnails/75.jpg)
Resources• https://www.php-fig.org/psr/psr-7• https://www.php-fig.org/psr/psr-15• https://www.php-fig.org/psr/psr-17
• https://mwop.net/blog/2015-01-26-psr-7-by-example.html• https://mwop.net/blog/2018-01-23-psr-15.html
Rob Allen ~ @akrabat