Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
The HttpKernelInterface is a lie (forumphp)
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Igor Wiedler
November 21, 2013
Programming
1.2k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
The HttpKernelInterface is a lie (forumphp)
Igor Wiedler
November 21, 2013
More Decks by Igor Wiedler
See All by Igor Wiedler
Redis Bedtime Stories
igorw
1
380
Wide Event Analytics (LISA19)
igorw
4
950
a day in the life of a request
igorw
0
180
production: an owner's manual
igorw
0
200
The Power of 2
igorw
0
350
LISP 1.5 Programmer's Manual: A Dramatic Reading
igorw
0
490
The Moral Character of Software
igorw
1
330
interdisciplinary computing (domcode)
igorw
0
330
miniKanren (clojure berlin)
igorw
1
340
Other Decks in Programming
See All in Programming
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
120
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
180
アクセシビリティから考える情報設計
high_g_engineer
0
380
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
220
AI活用は、個人から組織へ|マルチプレイヤーエージェントハーネス「QM」の社内活用事例 / AI use is moving from individuals to orgs
rkaga
1
160
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
200
Jetpack Compose メカニズム
skydoves
0
470
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
390
What We Talk About When We Talk About XP
m_seki
2
670
App Intentsのビルドプロセスを支える技術
kntkymt
0
420
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
2
300
FreeBSDでZabbixを動かす
kenkino
0
320
Featured
See All Featured
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
280
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Unsuck your backbone
ammeep
672
58k
HDC tutorial
michielstock
2
880
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
520
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.6k
Building Adaptive Systems
keathley
44
3.2k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
430
Transcript
Stack a PHP interface for framework- agnostic code sharing
the HttpKernelInterface is a lie
@igorwesome
None
“Interface” Protocol Communication Message passing
Catherine Please, from The Noun Project
Paulo Sá Ferreira - Purple Matter, from The Noun Project
hi!
None
10010101110100100
1001010111010010000110101 Massimiliano Mauro, from The Noun Project
Sergey Shmidt, from The Noun Project aloha!
yay!
00101000011101100102
None
None
None
None
Universal Interface
None
10010111001010001011
1234 4321
foo bar baz foo baz Patrick n Hawaii, from The
Noun Project
foo moo Anuar Zhumaev, from The Noun Project
find src -name '*.php' | grep -iv tests | cut
-f2- -d/ | cut -f1 -d\. | awk '{ print length, $0 }' | sort -n | tr / \\ ;
Tim Boelaars, from The Noun Project
None
nc
/\_/\ / 0 0 \ ====v==== \ W / |
| _ / ___ \ / / / \ \ | (((-----)))-' / ( ___ \__.=|___E /
None
data Dmitry Baranovskiy, from The Noun Project
xinetd
None
/etc/xinet.d/<service> service <service> { disable = no socket_type = stream
protocol = tcp user = <user> wait = no server = /usr/local/bin/<program> }
/etc/xinet.d/fortune service fortune { disable = no socket_type = stream
protocol = tcp user = xinetd wait = no server = /usr/local/bin/fortune }
#!/bin/bash fortune | cowsay
$ nc <host> 7777
$ nc <host> 7777 ______________________________________ < Eat right, stay fit,
and die anyway. > -------------------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
/etc/xinet.d/cowsay service cowsay { disable = no socket_type = stream
protocol = tcp user = xinetd wait = no server = /usr/games/cowsay }
$ echo 'moo' | nc <host> 7778
$ echo 'moo' | nc <host> 7778 _____ < moo
> ----- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
#!/usr/bin/php <?php ! while (!feof(STDIN)) { echo transform(fgets(STDIN)); }
cgi
The Common Gateway Interface (CGI) [22]! allows an HTTP [1],
[4] server and a CGI! script to share responsibility for responding! to client requests. RFC 3875
xinetd tcp http httpd
http httpd script cgi
script env vars data headers data
GET / HTTP/1.1 Host: igor.io Accept: */* REQUEST_METHOD = GET
PATH_INFO = / HTTP_HOST = igor.io HTTP_ACCEPT = */* SERVER_NAME = igor.io
Content-Type: text/html ! <!DOCTYPE html> <html> ... </html>
fcgi
script
sockets are the new pipes
• 1991: HTTP • 1993: CGI • 1995: PHP •
1996: FastCGI
• 1997: Java Servlet • 2003: Python WSGI • 2007:
Ruby Rack • 2009: Perl PSGI • 2011: Symfony2 HttpKernelInterface
rack
class HelloWorld def call(env) [ 200, {"Content-Type" => "text/plain"}, ["Hello
world!"] ] end end
sapi
$_SERVER header echo exit
HttpKernelInterface
interface HttpKernelInterface! {! /*** @return Response */! public function handle(Request
$request);! }
sapi kernel
None
“legacy” apps: it’s all great until exit;
myths: !
myths: caching
myths: caching (use varnish)
myths: caching (use varnish) functional tests
CgiHttpKernel adapter from kernel to cgi functional test “legacy” apps
kernel CGI
kernel CGI anything!
$kernel = new CgiHttpKernel(__DIR__.'/app'); ! $request = Request::create('/index.php'); $response =
$kernel->handle($request); ! var_dump($response->getContent());
use Symfony\Component\HttpKernel\Client; ! $client = new Client($kernel); ! $crawler =
$client->request('GET', '/index.php');
caution: it’s slow (WIP: FcgiHttpKernel)
Where is the value?
REQ REP
fcgi roles
authorizer httpd responder filter
rack middlewares
HttpKernel middlewares
$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() );
use Symfony\Component\HttpKernel\HttpCache\HttpCache; use Symfony\Component\HttpKernel\HttpCache\Store; $app = new HttpCache( $app, new
Store(__DIR__.'/cache') );
use Symfony\Component\HttpKernel\HttpCache\HttpCache; use Symfony\Component\HttpKernel\HttpCache\Store; $app = new HttpCache( $app, new
Store(__DIR__.'/cache') ); use varnish!
App Logger Authentication Session
None
do something before or after every request
different take on event listeners
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; } } 1 2 3
UrlMap $blog = new Silex\Application(); ! $blog->get('/', function () {
return 'This is the blog!'; }); ! $app = new Stack\UrlMap($app, [ '/blog' => $blog, ]);
Session $app = new CallableHttpKernel(function ($request) { $session = $request->getSession();
... }); ! $app = new Stack\Session($app);
OAuth $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');
Composition!
$stack = (new Stack\Builder()) ->push('Stack\Session') ->push('Igorw\Stack\OAuth', [...]) ->push('Foo'); ! $app
= $stack->resolve($app);
• GeoIp • IpRestrict • Backstage • Basic Authentication •
Hawk • CORS Community
It doesn’t stop there
• Authentication • Debug toolbar • Injected routes • Signed
cookies • Asset management • Force SSL • Error handling
( )
Choose wisely
Michael Rowe, from The Noun Project
• joind.in/9355 • stackphp.com • @stackphp • @igorwesome • github.com/igorw/CgiHttpKernel