Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
大統一PHP
uzulla
March 09, 2018
Programming
2
4.5k
大統一PHP
PHPerKaigi 2018 前夜祭🍻
2018/03/09 at coconeri
uzulla
March 09, 2018
Tweet
Share
More Decks by uzulla
See All by uzulla
uzulla
1
230
uzulla
0
200
uzulla
14
11k
uzulla
2
1.8k
uzulla
1
3.3k
uzulla
6
5.4k
uzulla
0
60
uzulla
0
170
uzulla
4
570
Other Decks in Programming
See All in Programming
pandanoir
0
270
imk2o
0
180
devinjeon
2
820
gtongy
0
420
commmune
0
620
tmyk110
1
110
manfredsteyer
PRO
0
260
d_endo
1
480
emberconf
0
130
shiba6v
0
200
minecr
0
110
kubode
1
170
Featured
See All Featured
cromwellryan
104
6.3k
ufuk
56
5.5k
holman
447
140k
deanohume
294
28k
akmur
252
19k
andyhume
64
3.8k
philhawksworth
190
17k
garrettdimon
289
110k
dotmariusz
94
5.5k
bryan
32
3.5k
hursman
107
9.3k
maggiecrowley
10
540
Transcript
େ౷ҰPHP 2018/03/09 PHPerKaigi 2018 લࡇ
uzullaͰ͢
!ɹ
None
https://www.youtube.com/watch?v=2tZxNtn0kDc • PerlͷΧϯϑΝϨϯεͰPHPͷͰϕεττʔΫͬͨͭ • ʢ݁ՌɺͰւ֎ΧϯϑΝϨϯεʹɺӳޠ͕Θ͔ΒΜPHPer ͕ɺӳޠͰPerlτʔΫΛ͠ʹߦ͘Ӌ͜ͱʹͳͬͨɺΊͬͪΌ Α͔ͬͨʣ • ͏༰ݹ͍ʢ·ͩPHPΛΒͳ͍ਓʹྑ͍͔ʣͷͩ ͕ɺ͍·ͩʹײΛ͍ͨͩ͘
None
https://www.youtube.com/watch?v=XOlSMGHhfrY • php.iniʹ͍ͭͯ̍࣌ؒҎ্ʁͨͬΓͨ͠ • ·͋ɺPHPerͳΒݺٵͱಉ͘͡Β͍׳Ε͍ͯΔࣄͩͱࢥ͏ • ·ͩʹͨͭͱࢥ͏ʢͨͿΜʣ
None
https://www.youtube.com/watch?v=bVRgVgEf9Ho • ʮPHPͰεϚϗΞϓϦʂʯʮPHPͰεϚʔτσδλϧΧϝϥʂʯ • ࣄʹཱͨͳ͍ଟΊ • PHP͕͖ͳͷͰ • ࣗͷझຯͰ͢
͍
DISCLAIMER • ͜ͷτʔΫٕज़తͳڵຯΛຬͨͨ͢Ίͷख๏Ͱ͋Γɺৗ༻͢ ͖ͱ͍͑ͳ͍ख๏ؚ͕·Ε͍ͯ·͢ɻ • ʮ͏͚͍͍͝ʢͬͯΈͨΒ͏͍ͨ͝ʣʯతͳख๏͋Γ· ͢ɻ • ۀʹ͏લʹಉ྅ͱ૬ஊ͠·͠ΐ͏ʂ
ຊ
ʮ౷Ұʯ ɹ ʮී௨ʯ
ࢲ͕ײ͡Δ
Α͋͘Δ෩ܠ ʁɿʮPHPͷڥߏஙΑ͘Θ͔ΒΜʯ ࢲɿʮࢲΑ͘Θ͔ΒΜɺମ͕͔ͬͯʹಈ͘ʯ
1, PHPͰΞϓϦΛಈ͔͢ʮڥʯ͕৭ʑ͋Γ͗͢Δ • Apache(+mod_php) • Apache with php-cgi • nginx
with php-fpm+php-cgi(FastCGI) • IIS with php-cgi(FastCGIɺPMIIS͕ߦ͏) • h2o with php-cgi(FastCGIɺPMh2o͕ߦ͏ʣ • PHP on GAE(ṖͷPHP) • HHVMʢ୯ମͰhttpdʹͳΔʣ
ී௨(?) • nginxͷhttpd + httpΛΔΞϓϦ • 㙽ʹ֯ΞϓϦhttpΛΔ • ʢPHPFastCGI…ΊΜͲ͍…ʣ
2, PHPΛͲ͔͜Βͬͯ͘Δʁ • yum,apt (Linux • installer (Windows • Brew
(Mac • php-build (Linux,Mac • ྑϏϧυ (tar ball͔ΒϏϧυ • ࣗՈrpm
ී௨(?) • ·͋ɺLLͳΒ͜͜ΒΜେࠩͳ͍…ͷ͕ͩ • goͱ͔ϫϯόΠφϦ • ʮCͱ͔so͕͋Δ͔ΒʯʮsoͳΜͩʯ • ʮࠓ͙͢μϯϩʔυʯ •
ʮαʔόϨεόΠφϦ͍Βͳ͍ͧʂʯʮͦ͏͍͏Ͱͳ ͍Ͱ͢…ʯ
PHPόΠφϦ৭ʑ͋Δ • php(-cli) • php-cgi • php-fpm(+php-cgi) • mod_php(.soɺ.dllʣ •
PHPerͳΒ͜ΕΒΛ֮ࣗతʹʮ࡞Εʯ·͢ΑͶ
ී௨ʢʁʣ • ʮී௨Ͳ͏ͳͷʁʯʮී௨Ұݸ͚ͩͩΑʯ • PerlͳΒperlʂʂRubyͳΒrubyʂʂ • ʢbundler,cartonͳͲπʔϧͰ͢ʣ • ʮmod_perlʁʯʮο಄͕ʯ •
ʮmod_rubyʯʮૉਓͳͷͰΈͨ͜ͱͳ͍Ͱ͢ʯ • GoͳΒίϯύΠϧޙόΠφϦ
3, C֦ுʢPeclʣ • peclίϚϯυͰάϩʔόϧʹೖΕΔ • ྑϏϧυͰάϩʔόϧʹೖΕΔ • yum,aptͰೖΕΔ • php.iniͰࣄલϩʔυ͢Δ
ී௨ʢʁʣ • ʮcpanm -lͰϥΠϒϥϦͱಉ༷ʹϩʔΧϧʹೖΕΔʯ • ʮbundlerͰϥΠϒϥϦͱಉ༷ʹϩʔΧϧʹೖΕΔʯ • ༁ɿʢcomposer install͢ΔͱɺvendorͷԼʹC֦ு͕ ೖΔʣ
• ※ ·͋͜Εඞͣͦ͏Ͱͳ͍͕ɺPHPͩͱແ༻Ͱάϩʔ όϧʹೖΔΑͶ • ʮpeclͬͯͳʹʁcomposerͰ͍Βͳ͍ͷʁΉ͔͍ͣ͠ʂʯ
PHPଉΛ͢ΔΑ͏ʹ͜͜ΒΜΛཧղ͠ɺ͏͕… • ී௨ɺ͜͜·ͰόϦΤʔγϣϯͳ͍ͷͰɺඇPHPerࠔ • Ͱɺզʑʹͳͬͯͳ͍ • օ͞Μ͍͔͢͝Β • PHP͘ΘΕ͍ͯΔ͔Βඋ͞Ε͍ͯΔ •
͔͠͠ɺීஈgoͳͲΛ͍ͬͯΔਓʹΑ͘Θ͔ΒΜΒ͍͠ • ͜·ͬͨ͜·ͬͨ
·ͱΊΔͱ • ී௨ͷਓ͔Βݟͯɺʮී௨ʯͰͳ͍PHP • (ʮී௨ʯͷఆٛ͜͜Ͱ͠·ͤΜʂʂ) • அઈΛײ͡Δ… • ʮΑ͠ɺී௨ʢʁʣʹ͋Θ͍ͤͯ͜͏ʂʯ
ʮ౷Ұ͍ͯͧ͘͠ʂʯ
͍
ͱɺ͍͏͜ͱͰ
ͱΓ·ɺhttpdʹͳΖ͏ʂʢʁʣ
࠶ܝʣଞͷݴޠͰ… • go → ͕ࣗhttpdʹͳΔ • ruby → ͕ࣗhttpdʹͳΔ •
Perl → ͕ࣗhttpdʹͳΔ • PHP → Apache͕͍Δ
ʮͱʹ͔͘httpdʹͳΔͷ͕ී௨ʂ Զී௨ʹͳ͍ͬͯͧ͘ʂʂʂʯ • ※ ཁग़య • ※ ಠࣗղऍ
ͪΖΜզʑhttpdʹ ͳΕ·͢
(Builtin Serverʁ͋Ε։ൃ༻͔ͩΒ…)
ͱ͍͏͜ͱͰ ͬͯΈΑ͏
Slim framework Ͱ࣮ྫ
ී௨ͷslim <?php require "vendor/autoload.php"; $container = new \Slim\Container; $app =
new \Slim\App($container); $app->get('/', function ($request, $response) { return $response->write("hello!!"); }); $app->run();
ReactPHPΛ͔ͭͬͨ Slim
reactΒͳ͍ਓ • ΠϕϯτۦಈͰ༷ʑͳॲཧΛ͢ΔϥΠϒϥϦ • ͳΜͰਓͱมΘͬͨ͜ͱ͕͖ͳਓʹ͓͢͢Ί • PHP୯ମͰhttpdʹͳΕΔκʂ • (ผͷεϥΠυͰઆ໌ͯ͠·͢)
<?php require "vendor/autoload.php"; $loop = React\EventLoop\Factory::create(); $server = new \React\Http\Server(array(
function (\Psr\Http\Message\ServerRequestInterface $request) { $container = new \Slim\Container; $app = new \Slim\App($container); // !slimͷrequestΛɺreact͕࡞ͬͨͷʹࠩ͠ସ͑ $container['request'] = function ($container) use ($request) { return $request; }; // ಛʹมΘΒͣ $app->get('/', function ($request, $response) { return $response->write("hello!!"); }); // !ҾʹtrueΛ͍ΕΔͱɺresponse ͕ؼ͖ͬͯ·͢ͷͰɺͦΕΛreact return $app->run(true); } )); $socket = new React\Socket\Server(8888, $loop); $server->listen($socket); $loop->run();
demo $ php main.php • ͱ͘ʹ͠·ͤΜʂޙͰʹͨΑ͏ͳ͜ͱΔ
SlimͱreactPHPPSR-7ରԠͳͷͰ • ͜Μͳ෩ʹͿͬ͜Ίಈ͘ʢͣʣ • ϫϯλονͰҠ২͕Ͱ͖ΔΘ͚Ͱͳ͍ • PSR-7 ରԠͱͦ͏͍͏ҙຯͰͳ͍ • ͜ΕผʹߴͰͳ͍ʢ࠷దԽγϯάϧτϯԽͯ͠ͳ
͍ʣ • ϒϩοΩϯάΛߟ͑ΔͱΉ͠Ζ͍ࣄ
օ͞Μʣʮ͋Ε…ʁҙ֎ͱ؆୯ͳͷͰ…ʁʯ
ͦΕͲ͏͔ͳʁ
ʮී௨ʯͷͨΊʹɺ৭ʑΔ͜ͱ͋Δ • httpdͷΘΓʹ੩తϑΝΠϧ৴ʢAPIͳΒෆཁ͕ͩ • ΤϥʔϋϯυϦϯά • ϩΨʔ • ηογϣϯʢCSRFͷͨΊʣ •
ޙड़͠·͢ • etc...
༨ஊ PSR-7ͱ(ৄࡉάάͬͯ) • ͍ΘΏΔʮ$_POSTͰಡΈࠐΈɺechoͰग़ྗʯΛ͠ͳ͍ • request/responseΦϒδΣΫτΛಡΜͩΓੜͨ͠Γͯ͠ɺ ೖग़ྗΛOOPͰऔΓѻ͏ • ʮ̍ϦΫΤετ̍ϓϩηεʯͷϝϦοτͰ͋Δεʔύʔάϩʔ όϧΛഉআ͠ɺʮNϦΫΤετɺ̍ϓϩηεʯΛ࣮ݱͨ͠Γɺς
ελϒϧʹͨ͠ΓɺϞδϡϥʔԽʢϛυϧΣΞԽʣ͕Ͱ͖Δ Α͏ʹͳΔͳͲ͕͋Δɻ
࣮ࡍʹαϯϓϧΞϓϦΛҠ২ͯ͠Έͨ • Tinitterͱ͍͏ɺஶʮWebΞϓϦΤϯδχΞཆಡຊʯͷα ϯϓϧܝࣔ൘ΞϓϦΛҠ২ • ʢPHP7ରԠͨ͠ΓɺSlim Framework3ʹରԠͤͨ͞Γɺ ORMΛࣺ͛ͯͨΓ͢Δͷʹ͕͔͔࣌ؒͬͨ…ʣ • https://github.com/uzulla/Tinitter
• (ͷ reactize ϒϥϯν)
demo • վमલͷී௨ͷTinitter • Ͳ͏ͱ͍͏͜ͱͳ͍͕ɺBuiltin serverͰ͏͔͝͠ͱΔͧ ͱ͍͏ɻ
reactͱSlimΛͭͳ͙ • ͜͜͢Ͱʹઆ໌ࡁΈͳͷͰলུ
੩తϑΝΠϧ৴ • ͜Ε؆୯ɺϛυϧΣΞΛΞϓϦͷલʹࠩ͠ࠐΉ͚ͩ • ʢϛυϧΣΞʹ͍ͭͯޙड़ʣ • ΞϓϦΑΓલʹ͜͞͠ΊɺϑΝΠϧ͕ͳ͚ΕΞϓϦʹ౸ୡ ͢Δ new WebrootPreloadMiddleware(__DIR__."/htdocs"),
༨ஊ ϛυϧΣΞͱʁ • PSR-7(ҎޙPSR-15ؚΉ)ରԠͷϛυϧΣΞͱɺελο Ϋͨ͠ϛυϧΣΞΛReq/ResΦϒδΣΫτΛ௨ա༷ͤͯ͞ʑ ͳલॲཧɺޙॲཧΛߦ͏ɻ • CSRFɺΞΫηε੍ݶɺηογϣϯͳͲɻ • PSR-7ରԠͷʮϑϨʔϜϫʔΫʯɺجຊϛυϧΣΞͱͯ͠
࣮͞ΕΔɻ
1 1 quote the image from http://www.darrenmothersele.com/blog/2017/03/28/php-middleware/
$server = new Server(array( // ΤϥʔϋϯυϦϯά ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ function (ServerRequestInterface $request,
callable $next) { return $next($request); /* ུ */ }, // ੩తϑΝΠϧ৴ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ new WebrootPreloadMiddleware(__DIR__."/htdocs"), // ηογϣϯ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ new SessionMiddleware(/* ུ */), // csrfରࡦ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ function (ServerRequestInterface $request, callable $next) { /* ུ */ return $next($request); }, // ΣϒΞϓϦ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ function (ServerRequestInterface $request) { $app = new \Slim\App($container); /* ུ */ return $app->run(true); // Σϒຊମ࣮ߦɺ͜͜Ͱnext͕ͳ͍ } ));
ݟ͑ͳ͍ͷͰൈਮ֦େ
$server = new Server([ // ྻͰϛυϧΣΞΛొ͢Δ // !ΤϥʔϋϯυϦϯάϛυϧΣΞ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ function
($request, $next) { // " req(Πϯελϯε)ͱnext(ؔ)ΛऔΔ return $next($request); // " ࣍ /* ུ */ }, // !੩తϑΝΠϧ৴ϛυϧΣΞ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ new WebrootPreloadMiddleware(__DIR__."/htdocs"), // " $this->__invoke() // !ΣϒΞϓϦʢϛυϧΣΞʣ ʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹʹ function ($request) { // ࣍͜͜(next)͕ͳ͍ $app = new \Slim\App($container); /* ུ */ return $app->run(true); // " ΣϒΞϓϦຊମ࣮ߦɺres(Πϯελϯε)Λreturn } ]);
• ελοΫ͕RequestΠϯελϯεΛϦϨʔ͢ΔΑ͏ʹ্͔ΒԼ ʹ࣮ߦ͞Εɺ ɹ$next($request)ͰResponseΠϯελϯε্͕ʹ·ͨͬͯ ͍͘ɻ • ్தͰ্ʹฦͯ͠͠·͏͜ͱͰ͖Δ • ੩తϑΝΠϧ৴ͰฦͤΕɺͦͷԼʹ͍͔ͳ͍ •
͜ͷ͋ͨΓɺ࠷ۙͰPSR-15ͰҾͷ༷͕ࣜมΘΔ ɹʢ͕ɺجຊಉ͡ʣ
༨ஊʢύον͕ඞཁͰͨ͠ʣ • ͦͷ··Ͱಈ͔ͳ͔ͬͨ • mimeΛर͑ͳ͍ͱɺnull͕Ͱ͖ͯͯམͪΔ • PatchedWebrootPreloadMiddlewareʹίϐͬͯಀ͛ͨ
ΤϥʔϋϯυϦϯά • ΤϥʔϋϯυϦϯά͕ඞཁ • ௨ৗΤϥʔ͕ը໘ʹग़ͳ͍ɺϩάʹग़ͳ͍
function (ServerRequestInterface $request, callable $next) { $promise = new React\Promise\Promise(
function ($resolve) use ($next, $request) { $resolve($next($request)); } ); // ྫ֎͕͕͋ͬͨΒɺ!͕࣮ߦ͞ΕΔ return $promise->then(null, function (Throwable $e) { // Throwable͕ྑ͍ͱࢥ͏ error_log("ERROR:" . $e->getMessage()); error_log($e->getTraceAsString()); return new Response( 500, array(), 'Internal Server error' ); }); },
• ϛυϧΣΞͱͯ͠ɺྫ֎ΛͳΜͰΩϟον͢Δ܅Λ࡞Δ • ྫ֎͕͕͖͋ͬͯͨΒɺΩϟονͯ͠Τϥʔը໘Λදࣔ͢Δ • ྫ֎ͷͪड͚reactͷPromiseΛ͔ͭͬͯͪड͚ • ମࡋझຯͰ͢Ͷɺࣗ͝༝ʹͲ͏ͧ
ηογϣϯ • ϩάΠϯCSRFͷͨΊʹඞཁ • PSR-7ʹʮηογϣϯऔΓܾΊ͕ͳ͍ʯ • $_SESSIONεʔύʔάϩʔόϧͳͷͰ ʮಉ࣌NϦΫΤετ1ϓϩηεʯෆՄ • $_SESSIONʹ͋·͔͞ΕͨPHPerʹͩΔ͍
• ͱ͍͑ϛυϧΣΞͰ࣮͞Εͨͷ͋Δ
// ηογϣϯ new \WyriHaximus\React\Http\Middleware\SessionMiddleware( 'MySessionCookie', $cache, // Instance implementing React\Cache\CacheInterface
[ // Optional array with cookie settings, order matters 0, // expiresAt, int, default '', // path, string, default '', // domain, string, default false, // secure, bool, default false // httpOnly, bool, default ] ),
༨ஊ • PSR-7ରԠͷηογϣϯ৭ʑ͋Δ͕ɺCookieʹ͍ΕΔ͕ͭ ଟ͍(ྫ:psr7-sessions/storageless) • PHPerͱͯ͠ɺΘ͔ΔɺΘ͔Δͷ͕ͩ…ʔϜ…ͱͳͬͯ͠· ͏͕ɺલड़ͷେৎɺσʔλΛαʔόͰ࣋ͭ • σϑΥϧτͷετϨʔδΦϯϝϞϦͳͷͰɺࣗͰετϨ ʔδΛ࣮(React\Cache\CacheInterfaceΛ࣮ͨ͠
ͷ)͢ΔͱΑ͍ͩΖ͏ɻ
CSRFTokenͷʹΔ • Slim Framework 3ͷAddonͷCSRFGuard$_SESSIONΛͭ ͔͍ͬͯΔͷͰ͏͔͝ͳ͍ • ΑͬͯɺઌఔͷSessionMiddlewareΛ͔ͭͬͯࣗͰ࣮͢ Δ
function (ServerRequestInterface $request, callable $next) { // read session $session_obj
= $request->getAttribute(SessionMiddleware::ATTRIBUTE_NAME); $session = $session_obj->getContents(); if(!isset($session['csrf_token'])) { $session_obj->setContents(['csrf_token' => random_bytes(64)]); } $csrf_token = $session_obj->getContents()['csrf_token']; // POSTͳΒcheck token if(strtolower($request->getMethod()) === "post"){ $params = $request->getParsedBody(); if(!isset($params['csrf_token']) || $params['csrf_token'] !== $csrf_token){ error_log("invalid csrf_token"); return new Response(400, [], "invalid csrf_token"); } } // attributeʹtokenΛอ࣋ $request = $request->withAttribute('csrf_token', $csrf_token); return $next($request); },
csrfτʔΫϯΛformʹຒΊࠐΉॴ • csrfτʔΫϯΛΫϩʔδϟͰίϯςφʹ͍Ε͓ͯ͘ • Twig֦ுΛॻ͍ͯՃ͢Δ
// ίϯςφʹcsrf_tokenΛอ࣋͠ɺTwigϔϧύʹ͢ $csrf_token = $request->getAttribute('csrf_token'); $container['csrf_token'] = function ($c) use
($csrf_token){ return $csrf_token; }; $container->view->addExtension(new CsrfExtension($csrf_token));
<?php // TwigΤΫεςϯγϣϯྫ class CsrfExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface {
protected $csrf; public function __construct($token) { $this->csrf = $token; } public function getGlobals() { return ['csrf' => ['value' => $this->csrf] ]; } public function getName() { return 'my/csrf'; } }
<input type="hidden" name="csrf_token" value="{{csrf.value}}">
༨ஊ Attributeʹ͍ͭͯ • PSR-7ͷreqʹAttributeͱ͍͏ɺ࣍ͷϛυϧΣΞʹ͢ req͍Ε͓͚ͯΔใ͕͋Δ • (reqͳͷͰ)ࣗΑΓલͷϛυϧΣΞʹͲͤͳ͍Αʂ • AttributeΩʔ໊ແ๏ଳࣗ༝ʢϑϦʔμϜʣ •
ʢηογϣϯී௨͜͜ͱ͔͖·ͬͯ΄͍͠…ʣ
ϩΨʔ • লུ • echoͰerror_log()ͰmonologͰಈ͘ • monologͳΒɺγϯάϧτϯʹ͓ͯ͘͠ͱΦγϟϨʢʁʣ • ྫ֎ͷ$e->getMessage()ͱ$e->getTraceAsString()ͩ ͠ͱ͖ΌOKͰ͠ΐ
ͱ͍͏͜ͱͰ • ͏͘͝Α͏ʹͳͬͨ
<?php require "vendor/autoload.php"; require __DIR__ . '/config.php'; use \Psr\Http\Message\ServerRequestInterface; use
\React\Http\Server; use \React\Http\Response; $loop = React\EventLoop\Factory::create(); $cache = new \React\Cache\ArrayCache(); $server = new Server(array( // ΤϥʔϋϯυϦϯά function (ServerRequestInterface $request, callable $next) { $promise = new React\Promise\Promise(function ($resolve) use ($next, $request) { $resolve($next($request)); }); return $promise->then(null, function (Throwable $e) { error_log("ERROR:" . $e->getMessage()); error_log($e->getTraceAsString()); return new Response( 500, array(), 'Internal Server error' ); }); }, // ੩తϑΝΠϧ৴ new \WyriHaximus\React\Http\Middleware\WebrootPreloadMiddleware(__DIR__."/htdocs"), // ηογϣϯ new \WyriHaximus\React\Http\Middleware\SessionMiddleware( 'MySessionCookie', $cache, // Instance implementing React\Cache\CacheInterface [ // Optional array with cookie settings, order matters 0, // expiresAt, int, default '', // path, string, default '', // domain, string, default false, // secure, bool, default false // httpOnly, bool, default ] ), // csrfରࡦ function (ServerRequestInterface $request, callable $next) { // read session $session_obj = $request->getAttribute(\WyriHaximus\React\Http\Middleware\SessionMiddleware::ATTRIBUTE_NAME); $session = $session_obj->getContents(); if(!isset($session['csrf_token'])) { $csrf_token = base64_encode(random_bytes(64)); $session_obj->setContents([ 'csrf_token' => $csrf_token, ]); }else{ $csrf_token = $session['csrf_token']; } // check token if(strtolower($request->getMethod()) === "post"){ $params = $request->getParsedBody(); if(!isset($params['csrf_token']) || $params['csrf_token'] !== $csrf_token){ error_log("invalid csrf_token"); return new Response(400, [], "invalid csrf_token"); } } $request = $request->withAttribute('csrf_token', $csrf_token); return $next($request); }, // ΣϒΞϓϦ function (ServerRequestInterface $request) { // SlimॳظԽ $container = new \Slim\Container; $app = new \Slim\App($container); // reactͷrequestΛಥͬࠐΉ $container['request'] = function ($container) use ($request) { return $request; }; // Register Twig View helper $container['view'] = function ($c) { $view = new \Slim\Views\Twig(TEMPLATES_DIR_PATH, []); $view->addExtension(new \Slim\Views\TwigExtension($c['router'], '/')); return $view; }; // csrf_tokenΛอ࣋͠ɺTwigϔϧύʹ͢ $csrf_token = $request->getAttribute('csrf_token'); $container['csrf_token'] = function ($c) use ($csrf_token){ return $csrf_token; }; $container->view->addExtension(new \Tinitter\Misc\TwigExt\CsrfExtension($csrf_token)); // SlimʹϧʔτΛొ \Tinitter\Route::registration($container); // ࣮ߦ return $app->run(true); } )); $socket = new React\Socket\Server(8888, $loop); $server->listen($socket); $loop->run();
ʮ༷͔ͳʁʯ • ·͋ɺͬͨுͬͨͷίʔυͰ͚͢ͲɺGithubʹ͋͛ͯ͋Δͷ ͰɺޙͰݟ͍ͯͩ͘͞ɻ • https://github.com/uzulla/Tinitter/tree/ reactize
DEMO • ͱ͍ͬͯ·͋ɺݟͯͳʹ͕ҧ͏Θ͚Ͱ… • phpͰىಈ͠ͱΔͳʂͱ͍͏Ͱ͢ɻ
͜Εͷ͍͍ͱ͜Ζ • httpdෆཁʂʂ࠷ߴʂʂʢʁʣ • (ଟ͘ͷ߹)ςετϞοΫָ͕ɺαϒϦΫΤετϦϓϨΠ Έ͍ͨͳࣄָ • ͍ͭʹPHPʹγϯάϧτϯ͕…ʂ • ϦΫΤετຖͷʮnewʯΛݮͰ͖Δʢ͔ʣྫ͑ςϯϓ
ϨʔτɺϧʔλɺઃఆͷϩʔυɺϩΨʔɺDBଓ • ʢͨͩɺطଘͷFW·ͣߟྀͯ͠ͳ͍ͷͰࣗ࡞ෆՄආʣ
͜ΕͷͭΒ͍ͱ͜Ζ • εʔύʔάϩʔόϧ($_GET,$_POST,$_SESSION,$_COOKIE) ͑ͳ͍ • ࣮ߦίʔυ͕ίέΔͱαʔόʔ͕མͪΔ • PHP7͔ΒΤϥʔपΓ͕ྫ֎Ͱඋ͞ΕͨͷͰɺ͕ΜΕ େৎʢͨͿΜʣ •
ʮexitͨ͠Βࢮ͵ʯʮ͠ͳ͍Ͱʯ • ʮdieͨ͠Βࢮ͵ʯʮ͠ͳͳ͍Ͱʯ
• max_execution_time, memory_limitͰอޢ͕Ͱ͖ͳ͍ • ʢͨΓલ͕ͩʣൿͷhtaccess͔ͭ͑·ͤΜ͆ • ࣗ࡞ͨ͠ΓɺલஈͷhttpdͰ͔͚ྑ͍ • ҆શੑߴԽΛߟ͑ΔͱPDOར༻ͨΊΒ͏ •
reactamphp͕ఏڙ͢ΔͷΛ͔ͭ͏ • ʮmysql͋ΔͬΆ͍͚ͲϙεάϨʁʯʮ…redisͱ͔ ͋ΔΑʯʮ͏͓ͬͨͧ͜͏ʂʂʯ(ຊՈͰͳ͚Ε͋Δࣄ ͋Δ)
ҙ • ʢϑϨʔϜϫʔΫҎ֎ͷɺຊ࣭ͷʣॲཧ͕͍࣌ؒͳΒ͘ ͳΔʢ͜ͱ͋Δʣ • ॏ͍ॲཧେࠩͳ͍͠ɺΉ͠ΖѱԽ͢Δ͜ͱ͕ଟ͍ʢݸਓͷײ ʣ • APIͳΒ͍͚Δ…ࣄ…͋Δ
ʮPHPͷྑ͍͕ͳ͍͡Όͳ͍ʁʯ • ͍ • PHPͷྑ͍Ͱ͋Δʮϩόετʯʮઃܭ͕దͰ͋Δఔಈ ͘ʯ͕݁ߏͳ͘ͳΔ • ϑΝΠϧΛߋ৽ͨ͠Β࠶ىಈ͕ඞཁʹͳΔ • ϒϩοΩϯάͨ͠ΒࢮɺόονతͳॲཧΛͨ͠Β٧·ΔʢͷͰ
Γ͢ʣ
ͦΕͰ… • httpd͍Βͳ͍ɺphpphp(-cli)͚ͩͰ͍͍ɻ • νϡʔχϯά͢Εɺܰྔͳ༻్ͳΒૣ͍ʢ͜ͱ͋Δʣ • ʮຊͷγϯάϧτϯ͕΄͔ͬͨ͠Μͩ…ʯ • ͷϩϚϯ͕͋Δʢಠࣗղऍʣ
httpdΛphpʹ౷ҰͰ͖ ͨͧʂʢʁʣ
͍
͔͜͜Β༨ஊ εϥΠυͰݟͯΔਓ͚ ͕࣌ؒ༨ͬͨΒ͠·͢
͜͏͍ͬͨΠϕϯτۦಈͷͳʹΒྫ • reactPHP • areys • swoole
reactPHP • https://github.com/reactphp/http • ఀ͍͕ͯͨ͠ɺ෮׆ʂ • …ͱ͓͍͖ɺਖ਼݄ऴΘͬͨΒ·ͨࢭ·ͬͨ • ͱ͍͑ɺhttpd͍ͩͿྑ͘ͳͬͨɻͪΐͬͱલ·Ͱɺʮॻ ͘͜ͱͰ͖ΔΑʂʯͱ͍͏αϯϓϧίʔυͬΆ͍ײͩͬ͡
ͨɻ • POSTͷ࣮͕؆қ͗͢Δ͕͋ͬͨ
reactPHP PSR-7ରԠ • PSR-7ରԠͰ࣮͞ΕͨͷͰɺPSR-7ରԠͷFW͕Δʂ • …ͱ͍͏ͷӕͰ͢ɻଟ͘ͷFWάϩʔόϧΫϦʔϯͰͳ͍ (ಛʹɺηογϣϯͳͲ) • ଟগؾΛ͚ͭΕ͍͚Δ
• PSR-7ඇରԠͰLaravel(ྫ:mnvx/laravel-reactphp) SymfonyόΠϯσΟϯά͕͋Δʢ͕…ʣ
ͦͷଞ • process managerແ͍ͷͰɺӡ༻ʹผ్ systemd,supervisord,daemontoolsͳͲΛ͏ • Α͘ѱ͘γϯϓϧ • ʮߴʯͱ͍͏ͷӕͰ͢ɻC֦ுͷeventͳͲΛ͍Εͯɺಛఆ ͷ༻్Ͱɺҙਂ͔͚͘ʮ͍ࣄ͋Δʯͱࢥ͏
• ΠϕϯτۦಈηʔϑͳίʔυΛॻ͘ͷ݁ߏ͍ͨΜɺಛʹDB ଓͱ͔ɻ
aerys • https://github.com/amphp/aerys • amPHPͰ࣮͞Εͨhttpd • process manager͕͋Δʂ • PSR-7ͳʹͦΕ͏·͍ͷʁ(ಠࣗͷreq,res)
• ݁ߏ׆ൃ
• Static file serving • WebSockets • Dynamic app endpoint
routing • Name-based virtual hosting • Full TLS support • Customizable GZIP output compression • HTTP/2.0 support (pushͳͲ) • Middleware hooks
• άϨʔεϑϧϦελʔτ • ϓϩηεϚωʔδϟʢϫʔΧมߋͳͲʣ • Unix domain sock • ࣮ߦϢʔβʔมߋ
• Ϧόϓϩ • ηογϣϯʢRedisʣɺCookie • ͔ͳΓϓϩμΫγϣϯϨσΟײ͋ΔʢݸਓͷײͰ͢ʣ
<?php use Aerys\{ Host, Request, Response, Websocket, function root, function
router, function websocket }; $router = router() ->route("GET", "/", function(Request $req, Response $res) { $res->end("<html><body><h1>Hello, world.</h1></body></html>"); }); $root = root($docrootPath = __DIR__);// static file serving $fallback = function(Request $req, Response $res) { $res->end("<html><body><h1>Fallback \o/</h1></body></html>"); }; return (new Host)->expose("*", 1337)->use($router)->use($root)->use($fallback);
swoole • https://github.com/swoole/swoole-src • จ۟ͳ͠ʢʁʣͷproduction readyʂʢςϯηϯτ͕࣮༻͠ ͍ͯΔʣ • high performance
for PHP. • த՚+C֦ுύϫʔͰ̎̌̌ສഅྗʢʁʣ • ͪΌΜͱߋ৽͞ΕͯΔʂ͍͢͝ʂʂ
• ӳޠυΩϡϝϯτ͔ͳΓඋ͞Εͨʢͪΐͬͱલ·Ͱதࠃޠ ͔Γͩͬͨʣ • Linux,OSX,WindowsͰಈ͘ʢͱॻ͍ͯ͋Δ͕ͪΐ͍ඍົʣ • Ϗϧυָʢґଘ͕ͳ͍ʣ • IDE helper͋Δ
શʹ༨ஊͳSwooleͷ͍͢͝ͱ͜Ζ • ͳΜͱʂʂʂPHPͳͷʹʂʂʂCoroutineͱChan(nelʣ͕͋ ΔʂʂʂGo͔Αʂʂʂ
$chan = new Channel(1024 * 256); co::create(function () use ($chan){
while(1){ co::sleep(0.5); $chan->push("A"); } }); co::create(function () use ($chan) { while(1){ $ret = $chan->pop(); if(!$ret){ co::sleep(0.1); continue; } echo $ret; } });
• ͳ͓ɺOSXͩͱڍಈ͕͓͔͔ͬͨ͠ɻ·ΕʹηάΔɺsleep͕ ࢭ·Δɺcoroutine͕ฒ͠ͳ͍ɻ • ʢͨΊͨ͠ͷ͕ͪΐͬͱલͳͷͰ͏࣏ͬͯΔ͔ʣ • LinuxͩͱͪΌΜͱ͏͘͝งғؾ • ඇಉظ͚ͩͰͳ͍ɺϚϧνεϨουϚϧνϓϩηεͰ͑Δ ϩοΫmmapɺ҆શͳϩʔΧϧredisΈ͍ͨͳtableɺϓϩη
εϚωʔδϟ͋Γ…ຊՈʹऔΓࠐ·Εͯ͘Εʂʂʂʂ • ਖ਼ɺ֦ு͞Ε͗͢Ͱ
• HHVMͱ͕ͪ͏ํੑͰʢPHPͷ··ʢʁʣͰʣਐԽ͍ͤͯͬ͞ ͍ͯΔΑ͏ʹΈ͑ͯɺݸਓతʹײ͕͋Δ • ΈΜͳ͓ࠔΓʹͳΔDNSϦκϧόʢͷඇಉظͷͭʣ·Ͱඋ • ʮPHPʹcoroutinͳ͍Ζʯʮͤͳʯ • ࣮ࡍ݁ߏߴͩ͠ɺເͱϩϚϯ͕͍͢͝
͜ΕͰؾܰʹwaitΛ͔͚Δ͜ͱͰ͖Δ͠ɺདྷͷISUCON͜Ε ͩʂʢҧ ʢISUCON༑ୡืू͍ͯ͠·͢ʣ
ͬͨʂ͜ΕͰ͍͚Δʂʂ • C֦ுͳΜͩΑͳ͋… • ʮʢ͜͜Ͱ͍͏ʣେ౷Ұײʯബ͍ʢผʹ౷Ұ͠ͳ͍͍͚ͯ͘ Ͳʣ
࠶ܝʣଞͷݴޠɺC֦ுʮlibʯଆ ʹೖΔ • phpͩͱɺΠϯετʔϧͨ͠phpͷԼͷmodulesʹ͍Δ • php.iniʹextensions=hoge.so • Ͱ·͋ɺdl࣮ؔߦ࣌Ҿ͔͍͍ͭ͑ΜͩΑͶʂ • ͱ͍͏͜ͱͰɺಥવͰ͕͢ʮ΄͔ͷݴޠͷC֦ுͷී௨ʯΛճऩ
͢Δ͜ͱ͕Ͱ͖·ͨ͠Ͷɺʢಥવͷճऩʣ
ʢISUCONؒืूதͰ ͔͢ΒͶʁʣ
͜͜·Ͱ༨ஊ
͍
ࢲʮͲ͏Ͱ͔͢ʁhttpdʹͳΓ·ͨ͠Αʯ ʁʮϑΝΠϧ͕ͨ͘͞Μ͋Δͷ͕ͳ͋…ʯ ࢲʮͳΜͩͱʯ
̍ϑΝΠϧʹ͠ͳ͚Εʢ໋ײʣ • ͬͨΔ͔ʂ
౷Ұ͍ͯͧ͘͠ʂ
Phar • PHPͷίʔυσʔλΛύοΫͰ͖Δͷ • composer.phar͝ଘͰ͠ΐ͏ • file_get_contentsfopenʹphar://ʙΛ͢ͱத͕ݟΕ Δ • stubʹmainతͳͷΛηοτ͢ΕɺpharϑΝΠϧΛ
phpͰ࣮ߦͰ͖Δ • php hoge.phar
pharͷ࡞Γํ • boxΛ͔ͭ͏ͱ؆୯ • https://github.com/box-project/box2 • ʮpharΛͭ͘Δͷ໘ͳͷΛղܾ܅ʯ • box.jsonΛॻ͚ͩ͘ʂ •
ͪΌΜͱComposerͰ͍Εͨͷಈ͘
ͱΓ͋͑ͣɺ͖ͬ͞ͷ reactPHPͰ࡞ͬͯΈΔ
box.json { "directories": ["htdocs","lib","templates","vendor"], "files": ["config.php","main.php"], "main": "main.php", "output": "react_tinitter.phar",
"stub": true }
$ php -d phar.readonly=false ~/bin/box.phar build Building... • -d phar.readonly=falseσϑΥϧτͰPharͷʮॻ͖ࠐ
Έʯېࢭ͞Ε͍ͯΔͷͰࢦఆɻphp.iniͰ͍͍͚Ͳͬͪ͜ ͷ΄͏͕ૣ͍ΑͶ
• ͔ͳΓ͔͔࣌ؒΓ·͢ $ time php -d phar.readonly=false ~/bin/box.phar build Building...
real 4m13.202s user 1m51.980s sys 1m44.934s
real 4m13.202s
• ʮ…͖ͬͱxdebug͕͍ͬͯΔ͔Βͩ…ʯ • ʮ֦ுΛɺ-dͰՃͰ͖Δ͕ɺ࣮ߦ࣌ʹআ…ʯ • ʮ….gitҎԼ·ͰύοΫ͞Εͯͳ͍͔͜Εʁʁʯ
͔͠͠ɺੈքautoload͚ͩͰͳ ͍ • ex: ςϯϓϨʔτϑΝΠϧɺίϯϑΟά • (Tinitterͷ߹sqlite) ྫ PHP Warning:
file_get_contents(public/index.html): failed to open stream: No such file or directory in phar:///tmp/example.phar/bin/main on line 26
Phar::interceptFileFuncs(); • ࠷ߴؔfile_get_contentsfopenͳͲΛԣऔΓ͠·͢ • ͕͢͞C֦ுɺͦ͜ʹγϏΕΔಌΕΔ • /Ͱ࢝·Βͳ͍ʢ૬ରύεʣ߹ɺݱࡏͷPhar͔ΒಡΉ • __DIR__͔ͭ͑Δ(phar:///tmp/example.phar/bin) •
ʮେମʯͳΜͱ͔ಈͧ͘ɻ • reactͷ੩తϑΝΠϧ৴ΞυΦϯಈ͘
͔͠͠PDO͕͏͔͝ͳ͍ $ php react_tinitter.phar Slim Application Error: Type: PDOException Code:
14 Message: SQLSTATE[HY000] [14] unable to open database file
Phar::mount() • Phar֎ͷϑΝΠϧσΟϨΫτϦΛ͔͋ͨPharʹ͋Δ͔ͷ Α͏ʹࢀর͢Δ͜ͱ͕Ͱ͖Δʢલड़ͱΈ߹ΘͤΔࣄʹͳΔʣ • ྫɿpharͷ֎ʹ͋Δsqlite.dbΛɺதʹ͋ΔΑ͏ʹ͢Δ Phar::mount( 'sqlite.db', dirname(Phar::running(false)).'/sqlite.db' );
• ͜ͷ࣌ɺ__DIR__͕Phar෦ʹ͔Θͬͯ͠·͏ͷͰҙ • Α͘ΔPDO("sqlite:".__DIR__."/sqlite.db")Έ͍ͨ ͳͷɺ૬ରʹॻ͖͑·͠ΐ͏
Phar::running() • Pharʹ͠ͳ͍ͱಈ͔ͳ͍ͱ͔ແཧͳͷͰɺPharԽ͞Ε͍ͯΔ͔ ൱͔ΛΔͨΊʹ͔ͭ͏ • __FILE__ Έ͍ͨͳͷ͕ฦ͞ΕΔɺ֎ͳΒfalse • ҾʹfalseͰɺPharࣗମͷύεΛฦ͢ $isUnderPhar
= (Phar::running()!=="") ;
ͱ͍͏͜ͱͰ • ϒʔτετϥοϓʹͳΔmain.phpͷઌ಄ʹॻ͘ <?php if(Phar::running()!==""){ // under phar Phar::mount('sqlite.db', dirname(Phar::running(false)).'/sqlite.db');
Phar::interceptFileFuncs(); } require "vendor/autoload.php"; // ...
Ͱ͖ͨʂ • DEMO • ͯ͠ɺผʹΘΓө͑͠ͳ͍͔Βͳ…
ίʔυ͕େ౷ҰͰ͖ͨʂ
͍
ࢲɿʮ͜ΕͰ̍ϑΝΠϧʹͳͬͨʂʯ ʁɿʮ͑ͬɺίʔυͱόΠφϦͱผ͡ΌΜʯ ࢲɿʢͦΕบͳͷͰʁʁʁʁʣ
சੜɺ͞Βʹ౷Ұͩʂʂ • ͱ͍͏͜ͱͰͭͳ͍͖͛ͯ·͠ΐ͏
ग़མͪʣͬͨʂେ౷Ұͩʂʂ $ cat /usr/bin/php main.php > one-pack-php $ ./one-pack-php -r
\ "eval('?>'.substr(file_get_contents('one-pack-php'), strlen(file_get_contents('/usr/bin/php'))));" • ̍ϑΝΠϧʹόΠφϦͱPHP͕͍ͬͨͧʂʂ
ղઆ cat php main.php > one-pack-php ! [PHPόΠφϦ] + [PHPίʔυ]
= [PHPόΠφϦ|PHPίʔυ]
$ ./one-pack-php \ # ͭͳ͛ͨPHP -r \ # ҾͰPHPίʔυࢦఆɺҎԼPHPίʔυ "eval('?>'.
// '<?php' Ͱ࢝·ΔίʔυΛಡΈࠐ·ͤΔҝ substr( // όΠφϦɺಡΈඈ͢ file_get_contents('one-pack-php'), // ͭͳ͛ͨPHPΛಡΈࠐΉ strlen( // ಡΈඈ͢͞ΛܾΊΔɺ͜͜ຊʹॻ͖͑Δ file_get_contents('/usr/bin/php')) // ඈ͢͞ ) );" ! [PHPόΠφϦ|PHPίʔυ] ^~~͜͜·ͰεΩοϓͯ͠ɺ ͦΕΛeval͍ͯ͠Δ
ʮͬͨͥʂ౷Ұͩʂʯ
օ͞Μͷײ • ʮ͏ͦͩΖʂʁʯ • ʮ͏ͦͰͳ͍ʯ
օ͞Μͷײ̎ • ʮਖ਼ؾͷࠫଡͰͳ͍ʯ • ʮ͔ͨ͠ʹʯ
ී௨ͷͨΊʹඇৗࣝΛ͠ͳ͚Ε…ʢʣ
ͬͨʂ͜ΕͰউརʂʂ • ͱ͓͍͍͕ͨ…
ͨΜͳΔPHPιʔεͳΒಈ͕͘… • pharfsʹ͓͔Ε͍ͯͳ͍ͱopenͰ͖ͳ͍ • ʢphp ext/pharͷιʔεΛΈΔͱ…ʣ • ͙͙͙
ͦͷ͜Ζࢲ YAPC::Okinawaͷҝɺ ԭೄʹ͍ͨ
• ʮ…͏ͬ͢Βؾ͍͍͕ͮͯͨɺ͜ΕແཧͳͷͰ…ʯ • (ԭೄ໊ίʔώʔ๐ΛҿΉ) • ʮ͍ͬͯ͏͔ɺfs͕ͳ͍ڥͳ͍Ζɺfs͔͓ͭ͏ʯ
• ͱ͍͏͜ͱͰਖ਼ؾʹͳΓPharͱPHP࿈݁ҊϘπʹͳΓ·ͨ͠ • ʢʮ౷Ұʯͷֶͼ͋ͬͨʣ • ʢ؇ืɿΑ͍ಀ͛ಓʣ
Ҋ bash ࣗݾղౚʹΑΔ࣮ߦ • ͪ͜Βඇৗʹ༝ॹਖ਼͍͠खஈͰ͢Ͷ • php, codeΛղౚ࣮ͯ͠ߦ
#!/bin/bash # head.sh function finish () { cd - rm
-rf $RUNPACKDIR exit } RUNPACKDIR=`mktemp -d /tmp/runpackphp.XXXXX` trap 'finish' {1,2,3,15} ENDLINE=$(grep --line-number --text "^##ENDLINE$" $0 | sed 's/:.*//') : $((ENDLINE++)) tail -n +$ENDLINE $0 | tar xzf - --directory $RUNPACKDIR cd $RUNPACKDIR $RUNPACKDIR/php $RUNPACKDIR/main.php cd - exit ##ENDLINE
#!/bin/sh # build.sh cd ../ tar czf --exclude-vcs selfbash/ball.tgz \
htdocs lib templates vendor \ sqlite.db main.php config.php php cd - cat head.sh ball.tgz > selfbash.sh chmod +x selfbash.sh
Ͱ͖ͨʂ • demo
͠͏ةಞͳਓͷҙ • ্ͷίʔυͷtargnu tarͰ͢ɺosxͰΔͳΒbrewͰ͍Ε ΔͳΓ͍ͯͩ͘͠͞ • ʢ͋Δ͋Δ…ʣ • sqlite.db·ͰಥͬࠐΉͱɺવ࠶ىಈͷͨͼʹר͖Γ· ͢ɻMysqlͱ͔͍ͬͯͩ͘͞ɻ
ʮ͍ͭʹʂେ౷Ұʂͩʂʯ
͍
ࢲɿʮ͜ΕͰͲ͏Ͱ͔͢ʂʯ ʁɿʮ͍ͬͯ͏͔ɺPHPDockerͱ͔ʹͯ͠ΠϝʔδαΠζͰ ͔͗͢ΔΘɺPHP͜Ε͔ͩΒʯ • ʢ͍ͬͯ͏͔͖ͬ͞ͷͰಥવPHP͕ϫϯόΠφϦͰίϐʔͯ͠Δ ॴ͕ੴͰ͢Ͷʣ
சੜখͯ͘͞͠Δʂʂ • ͍Ͱɺ̍όΠφϦͰɺখ͍͞PHPΛͭ͘Δ • ʢಥવͷϧʔϧɿҰݸͷϑΝΠϧͰ·ͬ͞Βͳڥʹ͍ͬͯ ͬͯ͏͚͝OKʣ
ઌऔΓΦνใ $ ./configure --disable-all --enable-mbstring --enable-json $ make all $
cp sapi/cli/php /path/to/php
Ͱ͖ͨʂʂ • ʮMacLinuxͰ͍͚ͨΑʂʯ • ʮ͍…ԶDocker͔ͩΒ…ʯ • ʮνοʯ
alpineͰಈ͘࠷খͷPHPΛ࡞͍ͬͯ͘ • ຌ༱ʹUbuntuͩͱ1GB͘Β͍͋Δɺ͔ͨ͠ʹ͖ͼ͍͠ • ެࣜϨγϐͩͱ60Mbyte͘Β͍ • ͑ͬɺ͜ΕͰσΧΠͷʁ
Φν ʢ7.2.2ͷྫͰ͢ʣ ./configure \ --disable-cgi --without-pear \ --enable-ftp --enable-mbstring --enable-mysqlnd
\ --with-openssl --with-zlib \ --disable-libxml --disable-dom --disable-xml \ --disable-simplexml --disable-xmlreader --disable-xmlwriter • ެࣜͷDockerFileΛվ͢Δͱָ • όΠφϦΛ͵͍ͯɺૉͷͷʹίϐʔ͔ͯͭ͠͏ • SSL࠷ॳ͔Β͋Δɺlibxml͕Ͱ͔͍ΜͩΑͳ͋…
݁Ռ $ docker image list REPOSITORY TAG IMAGE ID CREATED
SIZE miniphp latest fa69ea70ab4c 2 weeks ago 11.4MB php-7.2.2-cli-alpine3.7 1.0 0a93147b91ab 2 weeks ago 62.5MB
miniphp 11.4MB php-7.2.2-cli-alpine3.7 62.5MB • ʮ11Mbyteͩͧɺ͏ΏΔͯ͘͠Ε…ʯ
ͨͩɺผʹDockerΛ͔ͭΘͳ͍ͷͰ • ࣮ࡍʹ͜Μͳ͜ͱΛීஈ͠ͳ͍ • ͱΓ͋͑ͣ࡞ͬͨΜͩ
ʢ͜ͷ݁Ռ·͍ͩͬͯͬͯͳ͍ͷͰɺଓ͖͕͋Δ͔Θ͔Γ· ͤΜʣ
ͱ͍͏͜ͱͰɺ • PHP͕httpdʹͳΔΑ͏ʹͯ͠ • PHPΛϫϯόΠφϦʹͯ͠ • ࣗݾղౚܗࣜͰύοΫͯ͠ • ̍ϑΝΠϧʹ͢Δ͜ͱʹΑΓ •
ଞͷݴޠͷਓ͕͍͏ʢʁʣʮී௨ʯͬΆ͍ʢಠࣗݟղʣφχΧ ͕Ͱ͖ͨ
ʮ͜Ε͕ϫΠͷେ౷Ұʂʯ
! • ·ͱΊʹೖ͍͖ͬͯ·͢
·ͱΊ • ແʹapache+mod_phpɺ͋Δ͍nginx+php-fpmΛ͍· ͠ΐ͏ • ͦΕͰνϟϨϯδ͢Δਓɺͥͻͱ͓͠·͠ΐ͏ • ʮདྷ͋ͨΓͷISUCONʹSwooleͰग़Δ༑ୡΛืू͍ͯ͠· ͢ʂʯ
ʮԶ࢝͘Ί͔ͨΓ͔ͩΒͳɹ ɹ͜ͷͯ͠ͳ͘ԕ͍େ౷ҰΛΑ…ʯ (to be continued...) (࣭Ͳ͏ͧ) (ͳ͚Ε༨ஊ)