HTTP Middlewares in PHP by Eugene Dounar
-
Upload
minsk-php-user-group -
Category
Software
-
view
135 -
download
2
description
Transcript of HTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP
http://igor.io @igorwhiletrue @eugene_dounar
Interface?
interface A { function doSomething(); function doSomethingElse();}
Универсальный интерфейс
find src -name '*.php' | grep -iv tests |
cut -f2- -d/ | cut -f1 -d\. |
awk '{ print length, $0 }' | sort -n |
tr / \\ ;
nc
xinetd
cgi
RFC 3875
The Common Gateway Interface (CGI) [22] allows an HTTP [1], [4] server and a CGI script to share responsibility for responding to client requests.
scriptПеременные окружения
ENV
Заголовки
Тело ответа
GET / HTTP/1.1Host: igor.ioAccept: */*
REQUEST_METHOD = GETPATH_INFO = /HTTP_HOST = igor.ioHTTP_ACCEPT = */*SERVER_NAME = igor.io
Content-Type: text/html
<!DOCTYPE html><html>...</html>
fcgi
nginx
script
Python?
WSGI
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield 'Hello World\n'
Ruby?
app = lambda do |env| body = "Hello, World!" [200, { "Content-Type" => "text/plain", "Content-Length" => body.length.to_s }, [body]]end run app
PHP?
?
PHP?
sapi
$_SERVERheader()echoexit()
php_sapi_name()
➔ aolserver➔ apache➔ apache2filter➔ apache2handler➔ caudium➔ cgi (until PHP
5.3)➔ cgi-fcgi➔ cli➔ continuity➔ embed
➔ isapi➔ litespeed➔ milter➔ nsapi➔ phttpd➔ pi3web➔ roxen➔ thttpd➔ tux➔ webjame
s
Python :)Ruby :)PHP :(
HttpKernelInterface
<?php
namespace Symfony\Component\HttpKernel;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;interface HttpKernelInterface{ const MASTER_REQUEST = 1; const SUB_REQUEST = 2;
public function handle( Request $request, $type = self::MASTER_REQUEST, $catch = true );}
<?php
namespace Symfony\Component\HttpKernel;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;interface HttpKernelInterface{ const MASTER_REQUEST = 1; const SUB_REQUEST = 2;
public function handle( Request $request, $type = self::MASTER_REQUEST, $catch = true );}
kernel
sapi
Why?
Обернуть древний код для тестов?
Why?
Обернуть древний код для тестов?
exit(‘you lose’);
CgiHttpKernel
Адаптер CGI реализующий интерфейс HttpKernelInterface
Why?
Кэширование?
Why?
Кэширование?
$kernel = new AppCache($kernel);
Why?
Кэширование?
varnish
$kernel = new AppCache($kernel);
middleware
<?php$app = new CallableHttpKernel(function ($request) { return new Response('Hello World!');});
class Logger implements HttpKernelInterface{ private $app; private $logger; public function __construct(HttpKernelInterface $app, LoggerInterface $logger) { $this->app = $app; $this->logger = $logger; }
public function handle(Request $request, ...) { $response = $this->app->handle($request, $type, $catch); $this->log($request, $response);
return $response; }
private function log(Request $request, Response $response) { ... }}
$app = new Logger( $app, new Monolog\Logger());
Session
Authentication
Logger
App
Rack middlewares https://github.com/rack/rack/wiki/List-of-Middleware
WSGI middlewares http://wsgi.readthedocs.org/en/latest/libraries.html
HttpKernel middlewares ?
Идея: Выполнять код до и после
обработки каждого запроса
class Foo implements HttpKernelInterface{ private $app;
public function __construct(HttpKernelInterface $app) { $this->app = $app; }
public function handle(Request $request, ...) { $response = $this->app->handle($request, $type, $catch); return $response; }}
Идея: Выполнять код до и после
обработки каждого запроса
События?
$blog = new Silex\Application();$blog->get('/', function () { return 'This is the blog!';});$app = new Stack\UrlMap($app, [ '/blog' => $blog,]);
UrlMap
$app = new CallableHttpKernel(function ($request) { $session = $request->getSession(); ...});$app = new Stack\Session($app);
Session
$app = new Igorw\Stack\OAuth($app, [ 'key'=> 'foo', 'secret'=> 'bar', 'callback_url' => 'http://localhost:8080/auth/verify', 'success_url'=> '/', 'failure_url'=> '/auth',]);$app = new Stack\Session($app);
OAuth
$request->attributes->get('oauth.token');
Простая композиция:
$stack = (new Stack\Builder()) ->push('Stack\Session') ->push('Igorw\Stack\OAuth', [...]) ->push('Foo');$app = $stack->resolve($app);
Middlewares!
● HttpCache● GeoIp● Backstage● Basic Authentication● CORS● Firewall
● CookieGuard● IpRestrict● OAuth● Hawk● StackRobots
More?● Authentication (~Warden)● ForceSSL● Debug toolbar● ESI● OpenID● ...
stackphp.com
github.com/stackphp
@stackphp
“HttpKernel is a lie” by @igorwhiletrue