Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Slim Frameworkで始めるPHPのmiddleware
Search
YAMAOKA Hiroyuki
July 15, 2017
Technology
4
2.1k
Slim Frameworkで始めるPHPのmiddleware
2017年7月17日、PHPカンファレンス関西2017での発表資料です。
https://2017.kphpug.jp/
YAMAOKA Hiroyuki
July 15, 2017
Tweet
Share
More Decks by YAMAOKA Hiroyuki
See All by YAMAOKA Hiroyuki
エンジニアの「センス」とは何か / What is the sense of engineers
hiro_y
19
8.6k
CSRF対策のやり方、そろそろアップデートしませんか / Update your knowledge of CSRF protection
hiro_y
29
24k
PHPで任意精度演算を行って「正しい」金額計算をする方法 / Perform arbitrary precision arithmetic in PHP to achieve "accurate" monetary calculations
hiro_y
2
2.8k
PHPのバージョンアップ実際のところどうなの? / How actually upgrade of PHP is
hiro_y
3
730
PHPのDI、attributesとこれから / PHP DI with attributes
hiro_y
1
2.2k
PHPのアノテーションの仕組みとメリット・デメリット / About PHP annotations
hiro_y
1
8.3k
株式会社 USEN Media - PHPカンファレンス北海道2019 / 2019-09-21_phpcondo-2019_usen-media
hiro_y
0
210
PHPのmiddlewareを 使いこなすために
hiro_y
3
2.4k
Node.jsやPHPでも こわくないHeroku
hiro_y
1
1.6k
Other Decks in Technology
See All in Technology
レンジャーシステムズ | 会社紹介(採用ピッチ)
rssytems
0
150
AWS re:Invent 2024 ふりかえり
kongmingstrap
0
130
非機能品質を作り込むための実践アーキテクチャ
knih
3
700
Jetpack Composeで始めるServer Cache State
ogaclejapan
2
160
なぜCodeceptJSを選んだか
goataka
0
150
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
110
Snykで始めるセキュリティ担当者とSREと開発者が楽になる脆弱性対応 / Getting started with Snyk Vulnerability Response
yamaguchitk333
2
180
TSKaigi 2024 の登壇から広がったコミュニティ活動について
tsukuha
0
160
スタートアップで取り組んでいるAzureとMicrosoft 365のセキュリティ対策/How to Improve Azure and Microsoft 365 Security at Startup
yuj1osm
0
210
マルチプロダクト開発の現場でAWS Security Hubを1年以上運用して得た教訓
muziyoshiz
2
2.1k
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
1
110
新機能VPCリソースエンドポイント機能検証から得られた考察
duelist2020jp
0
210
Featured
See All Featured
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Mobile First: as difficult as doing things right
swwweet
222
9k
For a Future-Friendly Web
brad_frost
175
9.4k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Designing for humans not robots
tammielis
250
25k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
Thoughts on Productivity
jonyablonski
67
4.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
A Philosophy of Restraint
colly
203
16k
Transcript
4MJN'SBNFXPSLͰ࢝ΊΔ 1)1ͷNJEEMFXBSF 1)1ΧϯϑΝϨϯεؔ ߹ಉձࣾςϯϚυɹࢁԬ
ࣗݾհ ࢁԬ!IJSP@Z 1)1ͱ͔/PEFKTͱ͔ॻ͖·͢ Ұ൪͖ͳͷ$44 ߹ಉձࣾςϯϚυදࣾһ
߹ಉձࣾςϯϚυ ݄ઃཱʢظʣ දࣾһਓ!! Ϗδωεࢧԉࣄۀ αʔϏε։ൃࣄۀ
JSVDBNJNFNPDPOBTV
NJEEMFXBSFͱʁ ͱ͍͏Λ͠·͢
XFCΞϓϦέʔγϣϯͱ )551ͷϦΫΤετΛड͚औΓ ͍Ζ͍ΖॲཧΛͯ͠ ೝূͱ͔%#ʹσʔλอଘͱ͔ ͍ΘΏΔϏδωεϩδοΫ
)551ͷϨεϙϯεΛฦ͢
؆୯ʹඳ͘ͱ͜͏
ϑΟϧλʔͱ͍͏ൃ શϦΫΤετڞ௨ͷॲཧ ॲཧલͷϩάΠϯೝূ ॲཧલͷσʔλऔಘɹͳͲ ΞϓϦέʔγϣϯຊମͷલʹ ॲཧΛڬΊΔΑ͏ʹ͢ΕΑ͍ͷͰ
ϑΟϧλʔʢલॲཧʣ
ϑΟϧλʔͷൃɺଓ͖ શϦΫΤετڞ௨ͷॲཧɺ·ͩ͋Δ ॲཧޙͷϩΪϯά ॲཧޙʹ·ͱΊͯϝʔϧૹ৴ ΞϓϦέʔγϣϯຊମͷޙʹ ॲཧΛڬΊΔΑ͏ʹ͢Ε͍͍ΑͶ
ϑΟϧλʔʢޙॲཧʣ
͜͜Ͱ/PEFKTͷ &YQSFTTͷΛ͠·͢
&YQSFTT IUUQFYQSFTTKTDPN l'BTU VOPQJOJPOBUFE NJOJNBMJTUXFCGSBNFXPSLGPS /PEFKTz
/PEFKTͰҰ൪ΘΕ͍ͯΔ XFCΞϓϦέʔγϣϯϑϨʔϜϫʔΫ
)FMMP8PSME const express = require('express'); const app = express(); app.get('/',
function(req, res) { res.send('Hello World!'); }); app.listen(3000);
͖ͬ͞ͷਤ
&YQSFTTͷߏ SPVUJOH ϦΫΤετΛॲཧʹϚοϐϯά NJEEMFXBSF SPVUJOHͷաఔͰ ҙͷॲཧΛࠩ͠ࠐΉͨΊͷΈ
&YQSFTTͷNJEEMFXBSF ͍Ͳ͜Ζ ڞ௨ॲཧʢલॲཧɺޙॲཧʣ ͭͷSPVUJOHʹରͯ͠ෳ࿈݁Ͱ͖Δ OFYUDBMMCBDLΛݺͿͱ ࣍ͷNJEEMFXBSFʹॲཧ͕ҠΔ
࣮ߦͷॱংએݴॱ
NJEEMFXBSFͷجຊ function(req, res, next) { // Կ͔લॲཧΛ͢Δ next(); // ࣍ͷmiddlewareΛݺͿ
// Կ͔ޙॲཧΛ͢Δ };
NJEEMFXBSFͷྫ const myLogger = function(req, res, next) { console.log('Logged!'); next();
}; app.get('/', myLogger, function(req, res) { res.send('Hello World!'); });
NJEEMFXBSFͷྫ શ const myLogger = function(req, res, next) { console.log('Logged!');
next(); }; app.use(myLogger); // શϦΫΤετʹద༻ app.get('/', function(req, res) { res.send('Hello World!'); });
ೖΕࢠʹͳ͍ͬͯΔ
NJEEMFXBSFͷྫʢෳʣ const auth = function(req, res, next) {}; const logger
= function(req, res, next) {}; app.get('/', auth, logger, function(req, res) { res.send('Hello World!'); });
NJEEMFXBSFͷྫʢʁʣ const myLogger = function(req, res) { console.log('Logged!'); }; app.get('/',
function(req, res, next) { res.send('Hello World!'); next(); }, myLogger); // ॲཧ࣮ߦޙʹݺΕΔ
͋ΒΏΔॲཧ͕ NJEEMFXBSFͱͯ͠ ࣮ɾ࣮ߦ͞ΕΔੈք
ೖΕࢠঢ়ଶ
λϚωΪΈ͍ͨʁ QIPUPCZEBSXJO#FMMMJDFOTFEVOEFS$$#: IUUQTXXXqJDLSDPNQIPUPTEBSXJOCFMM
Ұํ1)1Ͱ ʢؼ͖ͬͯͨʂʣ
4UBDL1)1 IUUQTUBDLQIQDPN l$PNQPTJOH)UUQ,FSOFM*OUFSGBDF NJEEMFXBSFTTJODFz l8IBUEPXFXBOU 3FVTFBUUIF XFCMBZFSz
4ZNGPOZͷ)UUQ,FSOFM*OUFSGBDF
4UBDL1)1
ͰͦΖͦΖ 4MJN'SBNFXPSLͷ
4MJN'SBNFXPSLW IUUQTXXXTMJNGSBNFXPSLDPN )5513PVUFS .JEEMFXBSF 1434VQQPSU
%FQFOEFODZ*OKFDUJPO
143 IUUQXXXQIQpHPSHQTSQTS )551NFTTBHFJOUFSGBDFT 1TSa)UUQa.FTTBHFa3FRVFTU*OUFSGBDF 1TSa)UUQa.FTTBHFa3FTQPOTF*OUFSGBDF
XFCΞϓϦͷೖग़ྗͷඪ४Խ
)FMMP8PSME // autoloadͱ͔useলུ… $app = new \Slim\App(); $app->get('/', function($request, $response)
{ $response->getBody() ->write('Hello World!'); return $response; }); $app->run();
؆୯Ͱ͠ΐʁ
͍Α͍Α NJEEMFXBSFͷ
NJEEMFXBSFʢؔʣ function(Request $request, Response $response, callable $next): Response { //
Կ͔લॲཧΛ͢Δ $response = $next($request, $response); // Կ͔ޙॲཧΛ͢Δ return $response; };
NJEEMFXBSFʢΫϥεʣ class ExampleMiddleware { public function __invoke( Request $request, Response
$response, callable $next ): Response { // …ؔͷͱ͖ͱಉ͡ } }
NJEEMFXBSFͷద༻ $app->get('/', function($request, $response) { // Կ͔ॲཧͯ͠ResponseΛฦ͢ })->add(ExampleMiddleware::class); // ͠શॲཧʹڬΉͳΒ
$app->add(ExampleMiddleware::class);
DPOUSPMMFS // $app->get('/', ExampleAction::class); class ExampleAction { public function __invoke(
Request $request, Response $response, array $args): Response { return $response; } }
%*ίϯςφͱ Έ߹ΘͤΔͱ ͬͱศརʹ
4MJNͷ%*ίϯςφͷҐஔ͚ Πϯελϯεੜ%*ίϯςφͷ ͖ͳ%*ίϯςφʹࠩ͠ସ͑Մೳ 1JNQMF1)1%*"DDMJNBUF $POUBJOFS*OUFSPQ࣮ͷίϯςφ
143࣮ͷίϯςφʢ͔Βʣ
%*ίϯςφͱͷ૬ੑ @@JOWPLFϝιου͕͋ΕΑ͍ͷͰ DPOUSPMMFSNJEEMFXBSF ίϯετϥΫλΠϯδΣΫγϣϯ ҙͷΠϯελϯεΛͤΔ
NPEFMΫϥεͱ͔ɺSFOEFSFSͱ͔
DPOUSPMMFS /** @var \Slim\Views\Twig */ private $view; public fucntion __construct(Twig
$view) { $this->view = $view; } public function __invoke(Request $request, Response $response, array $args): Response { return $this->view->render($response, 'foo.twig'); }
Λͯ͠ɺ143ͷ
ؔ͋Γͦ͏ͳ143 IUUQXXXQIQpHPSHQTS 1)14UBOEBSET3FDPNNFOEBUJPOT 143)551.FTTBHF*OUFSGBDF"DDFQUFE 143$POUBJOFS*OUFSGBDF"DDFQUFE
143)551.JEEMFXBSFT%SBGU
143 "DDFQUFE %*ίϯςφͷJOUFSGBDFͷඪ४Խ 1TSa$POUBJOFSa$POUBJOFS*OUFSGBDF HFUͱIBTͷϝιουΛ࣋ͭ
143 %SBGU .JEEMFXBSF*OUFSGBDF NJEEMFXBSFࣗମʹؔ͢Δͷ %FMFHBUF*OUFSGBDF ҕઌίΞͷΞϓϦϨΠϠʔʁ
·ͩٞͷߦํ͕ఆ·͍ͬͯͳ͍
1)1ͷNJEEMFXBSFྲّྀ %PVCMF1BTT 4MJNͬͪ͜ GO SFRVFTU SFTQPOTF OFYU
SFTQPOTF 4JOHMF1BTT GO SFRVFTU OFYU SFTQPOTF
.JEEMFXBSF*OUFSGBDF namespace Psr\Http\ServerMiddleware; interface MiddlewareInterface { public function process( ServerRequestInterface
$request, DelegateInterface $delegate ): ResponseInterface; }
%FMFHBUF*OUFSGBDF namespace Psr\Http\ServerMiddleware; interface DelegateInterface { public function process( ServerRequestInterface
$request ): ResponseInterface; }
ଞͷϑϨʔϜϫʔΫͷ߹
-BSBWFM IUUQTMBSBWFMDPNEPDT NJEEMFXBSF 143ͳͲҙ͍ࣝͯ͠ͳ͍ ैདྷͷDPOUSPMMFSͷิॿతͳׂ ڞ௨ॲཧΛ࣮͢ΔͨΊͷΈ
-BSBWFMྫ class CheckAge { public function handle( \Illuminate\Http\Request $request, \Closure
$next) { // Կ͔ॲཧʢલͰޙΖͰʣ return $next($request); } } Route::get('/', function() { /* ॲཧ */ }) ->middleware(CheckAge::class);
$BLF1)1 $BLF1)1͔ΒNJEEMFXBSF͕͋Δ ࣮ํ๏4MJNͱ΄ͱΜͲಉ͕ͩ͡ɺ ਖ਼͜ͳΕ͍ͯͳ͍ײ͡ ΫϥεͰͳ͘ΠϯελϯεΛ͢ IUUQTXXXTMJEFTIBSFOFUNBSLTUPSZ
DBLFQIQUIFSPBEBIFBE
4ZNGPOZ NJEEMFXBSFʹ૬͢Δػೳͳ͍ ػೳͱͯ͠ϑΟϧλʔ͕͋Δ 4JMFYͰNJEEMFXBSFͱݺͿͷ͋Δ ͕ɺ͍ΘΏΔϑΟϧλʔͰ͔͠ͳ͍
;FOE&YQSFTTJWF IUUQTEPDT[FOEGSBNFXPSLDPN [FOEFYQSFTTJWF 143.JEEMFXBSF3PVUJOH%* 143ͳͲͷඪ४Λҙࣝ BDUJPOΫϥεNJEEMFXBSFͱ࣮ͯ͠
;FOE&YQSFTTJWFྫ $helloMiddleware = function ( ServerRequestInterface $request, DelegateInterface $delegate )
{ return new TextResponse('Hello', 200); }; // ͋Δ͍MiddlewareInterfaceΛ࣮ͨ͠Ϋϥε $app->get('/hello', $hellosMiddleware);
NJEEMFXBSF ͍͔͕Ͱ͔ͨ͠ʁ
·ͱΊ NJEEMFXBSFͱ͍͏ߟ͑ํΛΔ͜ͱ ॲཧΛNJEEMFXBSFͰׂ➡ςετ༰қੑ 143Ͱඪ४Խ͞ΕΔ͜ͱͰࠩ͠ସ͑Մೳʹ %*ίϯςφͱͷΈ߹Θͤɺศར
4MJNͱ͔;FOE&YQSFTTJWF໘ന͍Αʂ
͋Γ͕ͱ͏͍͟͝·ͨ͠ ࣭͕͋ΕͲ͏ͧ