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
20
8.9k
CSRF対策のやり方、そろそろアップデートしませんか / Update your knowledge of CSRF protection
hiro_y
29
25k
PHPで任意精度演算を行って「正しい」金額計算をする方法 / Perform arbitrary precision arithmetic in PHP to achieve "accurate" monetary calculations
hiro_y
2
2.9k
PHPのバージョンアップ実際のところどうなの? / How actually upgrade of PHP is
hiro_y
3
740
PHPのDI、attributesとこれから / PHP DI with attributes
hiro_y
1
2.2k
PHPのアノテーションの仕組みとメリット・デメリット / About PHP annotations
hiro_y
1
8.4k
株式会社 USEN Media - PHPカンファレンス北海道2019 / 2019-09-21_phpcondo-2019_usen-media
hiro_y
0
220
PHPのmiddlewareを 使いこなすために
hiro_y
3
2.4k
Node.jsやPHPでも こわくないHeroku
hiro_y
1
1.6k
Other Decks in Technology
See All in Technology
なぜfreeeはハブ・アンド・スポーク型の データメッシュアーキテクチャにチャレンジするのか?
shinichiro_joya
2
530
Cloudflareで実現する AIエージェント ワークフロー基盤
kmd09
0
290
2024AWSで個人的にアツかったアップデート
nagisa53
1
110
生成AIのビジネス活用
seosoft
0
110
メールヘッダーを見てみよう
hinono
0
120
.NET 最新アップデート ~ AI とクラウド時代のアプリモダナイゼーション
chack411
0
200
カップ麺の待ち時間(3分)でわかるPartyRockアップデート
ryutakondo
0
140
三菱電機で社内コミュニティを立ち上げた話
kurebayashi
1
360
embedパッケージを深掘りする / Deep Dive into embed Package in Go
task4233
1
220
AWSサービスアップデート 2024/12 Part3
nrinetcom
PRO
0
150
AWS Community Builderのススメ - みんなもCommunity Builderに応募しよう! -
smt7174
0
190
20250116_自部署内でAmazon Nova体験会をやってみた話
riz3f7
1
100
Featured
See All Featured
Fireside Chat
paigeccino
34
3.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
The Invisible Side of Design
smashingmag
299
50k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.4k
How to Think Like a Performance Engineer
csswizardry
22
1.3k
What's in a price? How to price your products and services
michaelherold
244
12k
Agile that works and the tools we love
rasmusluckow
328
21k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.1k
Building an army of robots
kneath
302
45k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
Designing Experiences People Love
moore
139
23k
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໘ന͍Αʂ
͋Γ͕ͱ͏͍͟͝·ͨ͠ ࣭͕͋ΕͲ͏ͧ