大統一PHP

271fad8d53cd1f12f2b4b6d38e3d7bd3?s=47 uzulla
March 09, 2018

 大統一PHP

PHPerKaigi 2018 前夜祭🍻
2018/03/09 at coconeri

271fad8d53cd1f12f2b4b6d38e3d7bd3?s=128

uzulla

March 09, 2018
Tweet

Transcript

  1. େ౷ҰPHP 2018/03/09 PHPerKaigi 2018 લ໷ࡇ

  2. uzullaͰ͢

  3. None
  4. https://www.youtube.com/watch?v=2tZxNtn0kDc • PerlͷΧϯϑΝϨϯεͰPHPͷ࿩ͰϕεττʔΫ໯ͬͨ΍ͭ • ʢ݁Ռɺ৆඼Ͱւ֎ΧϯϑΝϨϯεʹɺӳޠ͕Θ͔ΒΜPHPer ͕ɺӳޠͰPerlτʔΫΛ͠ʹߦ͘Ӌ໨͜ͱʹͳͬͨɺΊͬͪΌ Α͔ͬͨʣ • ΋͏಺༰͸ݹ͍ʢ·ͩPHPΛ஌Βͳ͍ਓʹ͸ྑ͍͔΋ʣͷͩ ͕ɺ͍·ͩʹײ૝Λ͍ͨͩ͘

  5. None
  6. https://www.youtube.com/watch?v=XOlSMGHhfrY • php.iniʹ͍ͭͯ̍࣌ؒҎ্ʁͨͬ΀Γ࿩ͨ͠ • ·͋ɺPHPerͳΒݺٵͱಉ͘͡Β͍׳Ε͍ͯΔࣄͩͱ͸ࢥ͏ • ·ͩ໾ʹͨͭͱࢥ͏ʢͨͿΜʣ

  7. None
  8. https://www.youtube.com/watch?v=bVRgVgEf9Ho • ʮPHPͰεϚϗΞϓϦʂʯʮPHPͰεϚʔτσδλϧΧϝϥʂʯ • ࢓ࣄʹ͸໾ཱͨͳ͍੒෼ଟΊ • PHP͕޷͖ͳͷͰ • ࣗ෼ͷझຯͰ͢

  9. ͸͍

  10. DISCLAIMER • ͜ͷτʔΫ͸ٕज़తͳڵຯΛຬͨͨ͢Ίͷख๏Ͱ͋Γɺৗ༻͢ ΂͖ͱ͸͍͑ͳ͍ख๏ؚ͕·Ε͍ͯ·͢ɻ • ʮ͏͚͝͹͍͍ʢ΍ͬͯΈͨΒ͏͍ͨ͝ʣʯతͳख๏΋͋Γ· ͢ɻ • ۀ຿ʹ࢖͏લʹಉ྅ͱ૬ஊ͠·͠ΐ͏ʂ

  11. ຊ୊

  12. ʮ౷Ұʯ ɹ ʮී௨ʯ

  13. ࢲ͕ײ͡Δ໰୊

  14. Α͋͘Δ෩ܠ ʁɿʮPHPͷ؀ڥߏஙΑ͘Θ͔ΒΜʯ ࢲɿʮࢲ΋Α͘Θ͔ΒΜɺମ͕͔ͬͯʹಈ͘ʯ

  15. 1, PHPͰΞϓϦΛಈ͔͢ʮ؀ڥʯ͕৭ʑ͋Γ͗͢Δ • Apache(+mod_php) • Apache with php-cgi • nginx

    with php-fpm+php-cgi(FastCGI) • IIS with php-cgi(FastCGIɺPM͸IIS͕ߦ͏) • h2o with php-cgi(FastCGIɺPM͸h2o͕ߦ͏ʣ • PHP on GAE(ṖͷPHP) • HHVMʢ୯ମͰhttpdʹͳΔʣ
  16. ී௨͸(?) • nginx౳ͷhttpd + httpΛ஻ΔΞϓϦ • 㙽ʹ֯ΞϓϦ͸httpΛ஻Δ • ʢPHP͸FastCGI…ΊΜͲ͍…ʣ

  17. 2, PHPΛͲ͔͜Β΋ͬͯ͘Δʁ • yum,apt (Linux • installer (Windows • Brew

    (Mac • php-build (Linux,Mac • ໺ྑϏϧυ (tar ball͔ΒϏϧυ • ࣗՈrpm
  18. ී௨͸(?) • ·͋ɺLLͳΒ͜͜Β΁Μ͸େࠩͳ͍…ͷ͕ͩ • goͱ͔͸ϫϯόΠφϦ • ʮCͱ͔͸so͕͋Δ͔ΒʯʮsoͳΜͩʯ • ʮࠓ͙͢μ΢ϯϩʔυʯ •

    ʮαʔόϨε͸όΠφϦ΋͍Βͳ͍ͧʂʯʮͦ͏͍͏࿩Ͱ͸ͳ ͍Ͱ͢…ʯ
  19. PHPόΠφϦ͸৭ʑ͋Δ • php(-cli) • php-cgi • php-fpm(+php-cgi) • mod_php(.soɺ.dllʣ •

    PHPerͳΒ͜ΕΒΛ֮ࣗతʹʮ࡞Εʯ·͢ΑͶ
  20. ී௨͸ʢʁʣ • ʮී௨͸Ͳ͏ͳͷʁʯʮී௨͸Ұݸ͚ͩͩΑʯ • PerlͳΒperlʂʂRubyͳΒrubyʂʂ • ʢbundler,cartonͳͲ͸πʔϧͰ͢ʣ • ʮmod_perl͸ʁʯʮ΢ο಄͕ʯ •

    ʮmod_rubyʯʮૉਓͳͷͰΈͨ͜ͱͳ͍Ͱ͢ʯ • GoͳΒίϯύΠϧޙόΠφϦ
  21. 3, C֦ுʢPeclʣ • peclίϚϯυͰάϩʔόϧʹೖΕΔ • ໺ྑϏϧυͰάϩʔόϧʹೖΕΔ • yum,apt౳ͰೖΕΔ • php.iniͰࣄલϩʔυ͢Δ

  22. ී௨͸ʢʁʣ • ʮcpanm -lͰϥΠϒϥϦͱಉ༷ʹϩʔΧϧʹೖΕΔʯ • ʮbundlerͰϥΠϒϥϦͱಉ༷ʹϩʔΧϧʹೖΕΔʯ • ຋༁ɿʢcomposer install͢ΔͱɺvendorͷԼʹC֦ு͕ ೖΔʣ

    • ※ ·͋͜Ε͸ඞͣͦ͏Ͱ͸ͳ͍͕ɺPHPͩͱ໰౴ແ༻Ͱάϩʔ όϧʹೖΔΑͶ • ʮpeclͬͯͳʹʁcomposerͰ͸͍Βͳ͍ͷʁΉ͔͍ͣ͠ʂʯ
  23. PHP͸ଉΛ͢ΔΑ͏ʹ͜͜Β΁ΜΛཧղ͠ɺ࢖͏͕… • ී௨ɺ͜͜·ͰόϦΤʔγϣϯͳ͍ͷͰɺඇPHPer͸ࠔ࿭ • Ͱ΋ɺզʑ͸໰୊ʹ͸ͳͬͯͳ͍ • օ͞Μ͸͍͔͢͝Β • PHP͸޿͘࢖ΘΕ͍ͯΔ͔Β੔උ͞Ε͍ͯΔ •

    ͔͠͠ɺීஈgoͳͲΛ࢖͍ͬͯΔਓʹ͸Α͘Θ͔ΒΜΒ͍͠ • ͜·ͬͨ͜·ͬͨ
  24. ·ͱΊΔͱ • ී௨ͷਓ͔Βݟͯɺʮී௨ʯͰ͸ͳ͍PHP • (ʮී௨ʯͷఆٛ͸͜͜Ͱ͸͠·ͤΜʂʂ) • அઈΛײ͡Δ… • ʮΑ͠ɺී௨ʢʁʣʹ͋Θ͍ͤͯ͜͏ʂʯ

  25. ʮ౷Ұ͍ͯͧ͘͠ʂʯ

  26. ͸͍

  27. ͱɺ͍͏͜ͱͰ

  28. ͱΓ·ɺhttpdʹͳΖ͏ʂʢʁʣ

  29. ࠶ܝʣଞͷݴޠͰ͸… • go → ࣗ෼͕httpdʹͳΔ • ruby → ࣗ෼͕httpdʹͳΔ •

    Perl → ࣗ෼͕httpdʹͳΔ • PHP → Apache౳͕͍Δ
  30. ʮͱʹ͔͘httpdʹͳΔͷ͕ී௨ʂ Զ͸ී௨ʹͳ͍ͬͯͧ͘ʂʂʂʯ • ※ ཁग़య • ※ ಠࣗղऍ

  31. ΋ͪΖΜզʑ΋httpdʹ ͳΕ·͢

  32. (Builtin Serverʁ͋Ε͸։ൃ༻͔ͩΒ…)

  33. ͱ͍͏͜ͱͰ ΍ͬͯΈΑ͏

  34. Slim framework Ͱ࣮૷ྫ

  35. ී௨ͷ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();
  36. ReactPHPΛ͔ͭͬͨ Slim

  37. react஌Βͳ͍ਓ΁ • ΠϕϯτۦಈͰ༷ʑͳॲཧΛ͢ΔϥΠϒϥϦ • ͳΜͰ΋ਓͱมΘͬͨ͜ͱ͕޷͖ͳਓʹ͸͓͢͢Ί • PHP୯ମͰhttpdʹͳΕΔκʂ • (ผͷεϥΠυͰઆ໌ͯ͠·͢)

  38. <?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();
  39. demo $ php main.php • ͸ͱ͘ʹ͠·ͤΜʂޙͰʹͨΑ͏ͳ͜ͱ΍Δ

  40. SlimͱreactPHP͸PSR-7ରԠͳͷͰ • ͜Μͳ෩ʹͿͬ͜Ί͹ಈ͘ʢ͸ͣʣ • ϫϯλονͰҠ২͕Ͱ͖ΔΘ͚Ͱ͸ͳ͍ • PSR-7 ରԠͱ͸ͦ͏͍͏ҙຯͰ͸ͳ͍ • ͜Ε͸ผʹߴ଎Ͱ͸ͳ͍ʢ࠷దԽ΍γϯάϧτϯԽ౳ͯ͠ͳ

    ͍ʣ • ϒϩοΩϯάΛߟ͑ΔͱΉ͠Ζ஗͍ࣄ΋
  41. օ͞Μʣʮ͋Ε…ʁҙ֎ͱ؆୯ͳͷͰ͸…ʁʯ

  42. ͦΕ͸Ͳ͏͔ͳʁ

  43. ʮී௨ʯͷͨΊʹɺ৭ʑ΍Δ͜ͱ͸͋Δ • httpdͷ୅ΘΓʹ੩తϑΝΠϧ഑৴ʢAPIͳΒෆཁ͕ͩ • ΤϥʔϋϯυϦϯά • ϩΨʔ • ηογϣϯʢCSRF౳ͷͨΊʣ •

    ޙड़͠·͢ • etc...
  44. ༨ஊ PSR-7ͱ͸(ৄࡉ͸άάͬͯ) • ͍ΘΏΔʮ$_POSTͰಡΈࠐΈɺechoͰग़ྗʯΛ͠ͳ͍ • request/responseΦϒδΣΫτΛಡΜͩΓੜ੒ͨ͠Γͯ͠ɺ ೖग़ྗΛOOPͰऔΓѻ͏ • ʮ̍ϦΫΤετ̍ϓϩηεʯͷϝϦοτͰ͋Δεʔύʔάϩʔ όϧΛഉআ͠ɺʮNϦΫΤετɺ̍ϓϩηεʯΛ࣮ݱͨ͠Γɺς

    ελϒϧʹͨ͠ΓɺϞδϡϥʔԽʢϛυϧ΢ΣΞԽʣ͕Ͱ͖Δ Α͏ʹͳΔͳͲ͕͋Δɻ
  45. ࣮ࡍʹαϯϓϧΞϓϦΛҠ২ͯ͠Έͨ • Tinitterͱ͍͏ɺ੿ஶʮWebΞϓϦΤϯδχΞཆ੒ಡຊʯͷα ϯϓϧܝࣔ൘ΞϓϦΛҠ২ • ʢPHP7ରԠͨ͠ΓɺSlim Framework3ʹରԠͤͨ͞Γɺ ORMΛ౤ࣺ͛ͯͨΓ͢Δͷʹ͕͔͔࣌ؒͬͨ…ʣ • https://github.com/uzulla/Tinitter

    • (ͷ reactize ϒϥϯν)
  46. demo • վमલͷී௨ͷTinitter • Ͳ͏ͱ͍͏͜ͱ͸ͳ͍͕ɺBuiltin serverͰ͏͔͝͠ͱΔͧ ͱ͍͏࿩ɻ

  47. reactͱSlimΛͭͳ͙ • ͜͜͸͢Ͱʹઆ໌ࡁΈͳͷͰলུ

  48. ੩తϑΝΠϧ഑৴ • ͜Ε͸؆୯ɺϛυϧ΢ΣΞΛΞϓϦͷલʹࠩ͠ࠐΉ͚ͩ • ʢϛυϧ΢ΣΞʹ͍ͭͯ͸ޙड़ʣ • ΞϓϦΑΓલʹ͜͞͠Ί͹ɺϑΝΠϧ͕ͳ͚Ε͹ΞϓϦʹ౸ୡ ͢Δ new WebrootPreloadMiddleware(__DIR__."/htdocs"),

  49. ༨ஊ ϛυϧ΢ΣΞͱ͸ʁ • PSR-7(ҎޙPSR-15΋ؚΉ)ରԠͷϛυϧ΢ΣΞͱ͸ɺελο Ϋͨ͠ϛυϧ΢ΣΞΛReq/ResΦϒδΣΫτΛ௨ա༷ͤͯ͞ʑ ͳલॲཧɺޙॲཧΛߦ͏ɻ • CSRFɺΞΫηε੍ݶɺηογϣϯͳͲɻ • PSR-7ରԠͷʮϑϨʔϜϫʔΫʯ͸ɺجຊϛυϧ΢ΣΞͱͯ͠

    ࣮૷͞ΕΔɻ
  50. 1 1 quote the image from http://www.darrenmothersele.com/blog/2017/03/28/php-middleware/

  51. $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͕ͳ͍ } ));
  52. ݟ͑ͳ͍ͷͰൈਮ֦େ

  53. $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 } ]);
  54. • ελοΫ͕RequestΠϯελϯεΛϦϨʔ͢ΔΑ͏ʹ্͔ΒԼ ʹ࣮ߦ͞Εɺ ɹ$next($request)ͰResponseΠϯελϯε্͕ʹ·ͨ໭ͬͯ ͍͘ɻ • ్தͰ্ʹฦͯ͠͠·͏͜ͱ΋Ͱ͖Δ • ੩తϑΝΠϧ഑৴ͰฦͤΕ͹ɺͦͷԼʹ͸͍͔ͳ͍ •

    ͜ͷ͋ͨΓɺ࠷ۙͰ͸PSR-15ͰҾ਺ͷ༷͕ࣜมΘΔ ɹʢ͕ɺجຊ͸ಉ͡ʣ
  55. ༨ஊʢύον͕ඞཁͰͨ͠ʣ • ͦͷ··Ͱಈ͔ͳ͔ͬͨ • mimeΛर͑ͳ͍ͱɺnull͕Ͱ͖ͯͯམͪΔ • PatchedWebrootPreloadMiddlewareʹίϐͬͯಀ͛ͨ

  56. ΤϥʔϋϯυϦϯά • ΤϥʔϋϯυϦϯά͕ඞཁ • ௨ৗΤϥʔ͕ը໘ʹ͸ग़ͳ͍ɺϩάʹ΋ग़ͳ͍

  57. 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' ); }); },
  58. • ϛυϧ΢ΣΞͱͯ͠ɺྫ֎ΛͳΜͰ΋Ωϟον͢Δ܅Λ࡞Δ • ྫ֎͕͕͖͋ͬͯͨΒɺΩϟονͯ͠Τϥʔը໘Λදࣔ͢Δ • ྫ֎ͷ଴ͪड͚͸reactͷPromiseΛ͔ͭͬͯ଴ͪड͚ • ମࡋ͸झຯͰ͢Ͷɺࣗ͝༝ʹͲ͏ͧ

  59. ηογϣϯ • ϩάΠϯ΍CSRF౳ͷͨΊʹඞཁ • PSR-7ʹ͸ʮηογϣϯ͸औΓܾΊ͕ͳ͍ʯ • $_SESSION͸εʔύʔάϩʔόϧͳͷͰ ʮಉ࣌NϦΫΤετ1ϓϩηεʯෆՄ • $_SESSIONʹ͋·΍͔͞ΕͨPHPerʹ͸ͩΔ͍

    • ͱ͸͍͑ϛυϧ΢ΣΞͰ࣮૷͞Εͨ΋ͷ΋͋Δ
  60. // ηογϣϯ 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 ] ),
  61. ༨ஊ • PSR-7ରԠͷηογϣϯ͸৭ʑ͋Δ͕ɺCookieʹ͍ΕΔ΍͕ͭ ଟ͍(ྫ:psr7-sessions/storageless) • PHPerͱͯ͠͸ɺΘ͔ΔɺΘ͔Δͷ͕ͩ…΢ʔϜ…ͱͳͬͯ͠· ͏͕ɺલड़ͷ͸େৎ෉ɺσʔλΛαʔόͰ࣋ͭ • σϑΥϧτͷετϨʔδ͸ΦϯϝϞϦͳͷͰɺࣗ෼ͰετϨ ʔδΛ࣮૷(React\Cache\CacheInterfaceΛ࣮૷ͨ͠΋

    ͷ)͢ΔͱΑ͍ͩΖ͏ɻ
  62. CSRFTokenͷ࿩ʹ໭Δ • Slim Framework 3ͷAddonͷCSRFGuard͸$_SESSIONΛͭ ͔͍ͬͯΔͷͰ͏͔͝ͳ͍ • ΑͬͯɺઌఔͷSessionMiddlewareΛ͔ͭͬͯࣗ෼Ͱ࣮૷͢ Δ

  63. 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); },
  64. csrfτʔΫϯΛformʹຒΊࠐΉॴ • csrfτʔΫϯΛΫϩʔδϟͰίϯςφʹ͍Ε͓ͯ͘ • Twig֦ுΛॻ͍ͯ௥Ճ͢Δ

  65. // ίϯςφʹ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));
  66. <?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'; } }
  67. <input type="hidden" name="csrf_token" value="{{csrf.value}}">

  68. ༨ஊ Attributeʹ͍ͭͯ • PSR-7ͷreqʹ͸Attributeͱ͍͏ɺ࣍ͷϛυϧ΢ΣΞʹ౉͢ req΁͍Ε͓͚ͯΔ৘ใ͕͋Δ • (req಺ͳͷͰ)ࣗ෼ΑΓલͷϛυϧ΢ΣΞʹ͸΋Ͳͤͳ͍Αʂ • AttributeΩʔ໊͸ແ๏஍ଳࣗ༝ʢϑϦʔμϜʣ •

    ʢηογϣϯ͸ී௨͜͜ͱ͔͖·ͬͯ΄͍͠…ʣ
  69. ϩΨʔ • লུ • echoͰ΋error_log()Ͱ΋monologͰ΋ಈ͘ • monologͳΒɺγϯάϧτϯʹ͓ͯ͘͠ͱΦγϟϨʢʁʣ • ྫ֎ͷ$e->getMessage()ͱ$e->getTraceAsString()ͩ ͠ͱ͖ΌOKͰ͠ΐ

  70. ͱ͍͏͜ͱͰ • ͏͘͝Α͏ʹͳͬͨ

  71. <?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();
  72. ʮ໛༷͔ͳʁʯ • ·͋ɺ੾ͬͨுͬͨͷίʔυͰ͚͢ͲɺGithubʹ͋͛ͯ͋Δͷ ͰɺޙͰݟ͍ͯͩ͘͞ɻ • https://github.com/uzulla/Tinitter/tree/ reactize

  73. DEMO • ͱ͍ͬͯ΋·͋ɺݟͯͳʹ͕ҧ͏Θ͚Ͱ΋… • phpͰ௚઀ىಈ͠ͱΔͳʂͱ͍͏࿩Ͱ͢ɻ

  74. ͜Εͷ͍͍ͱ͜Ζ • httpdෆཁʂʂ࠷ߴʂʂʢʁʣ • (ଟ͘ͷ৔߹)ςετ΍ϞοΫָ͕ɺαϒϦΫΤετ΍ϦϓϨΠ Έ͍ͨͳࣄ΋ָ • ͍ͭʹPHPʹ΋γϯάϧτϯ͕…ʂ • ϦΫΤετຖͷʮnewʯΛ࡟ݮͰ͖Δʢ͔΋ʣྫ͑͹ςϯϓ

    ϨʔτɺϧʔλɺઃఆͷϩʔυɺϩΨʔɺDB઀ଓ౳ • ʢͨͩɺطଘͷFW͸·ͣߟྀͯ͠ͳ͍ͷͰࣗ࡞ෆՄආʣ
  75. ͜ΕͷͭΒ͍ͱ͜Ζ • εʔύʔάϩʔόϧ($_GET,$_POST,$_SESSION,$_COOKIE) ͸࢖͑ͳ͍ • ࣮ߦίʔυ͕ίέΔͱαʔόʔ͕མͪΔ • PHP7͔Β͸ΤϥʔपΓ͕ྫ֎Ͱ੔උ͞ΕͨͷͰɺ͕Μ͹Ε͹ େৎ෉ʢͨͿΜʣ •

    ʮexitͨ͠Βࢮ͵ʯʮ͠ͳ͍Ͱʯ • ʮdieͨ͠Βࢮ͵ʯʮ͠ͳͳ͍Ͱʯ
  76. • max_execution_time, memory_limitͰอޢ͕Ͱ͖ͳ͍ • ʢ౰ͨΓલ͕ͩʣൿ఻ͷhtaccess͸͔ͭ͑·ͤΜ͆ • ࣗ࡞ͨ͠ΓɺલஈͷhttpdͰ͔͚͹ྑ͍ • ҆શੑ΍ߴ଎ԽΛߟ͑ΔͱPDOར༻ͨΊΒ͏ •

    react΍amphp͕ఏڙ͢Δ΋ͷΛ͔ͭ͏ • ʮmysql͸͋ΔͬΆ͍͚ͲϙεάϨ͸ʁʯʮ…redisͱ͔͸ ͋ΔΑʯʮ΋͏͓ͬͨͧ͜͏ʂʂʯ(ຊՈͰͳ͚Ε͹͋Δࣄ ΋͋Δ)
  77. ஫ҙ఺ • ʢϑϨʔϜϫʔΫ౳Ҏ֎ͷɺຊ࣭ͷʣॲཧ͕࣌ؒ୹͍ͳΒ଎͘ ͳΔʢ͜ͱ΋͋Δʣ • ॏ͍ॲཧ͸େࠩͳ͍͠ɺΉ͠ΖѱԽ͢Δ͜ͱ͕ଟ͍ʢݸਓͷײ ૝ʣ • APIͳΒ͍͚Δ…ࣄ΋…͋Δ

  78. ʮPHPͷྑ͍఺͕ͳ͍͡Όͳ͍ʁʯ • ͸͍ • PHPͷྑ͍఺Ͱ͋Δʮϩόετʯʮઃܭ͕ద౰Ͱ΋͋Δఔ౓ಈ ͘ʯ͕݁ߏͳ͘ͳΔ • ϑΝΠϧΛߋ৽ͨ͠Β࠶ىಈ͕ඞཁʹͳΔ • ϒϩοΩϯάͨ͠ΒࢮɺόονతͳॲཧΛͨ͠Β٧·ΔʢͷͰ

    ੾Γ཭͢ʣ
  79. ͦΕͰ΋… • httpd͍Βͳ͍ɺphp͸php(-cli)͚ͩͰ͍͍ɻ • νϡʔχϯά͢Ε͹ɺܰྔͳ༻్ͳΒૣ͍ʢ͜ͱ΋͋Δʣ • ʮຊ෺ͷγϯάϧτϯ͕΄͔ͬͨ͠Μͩ…ʯ • ׽ͷϩϚϯ͕͋Δʢಠࣗղऍʣ

  80. httpdΛphpʹ౷ҰͰ͖ ͨͧʂʢʁʣ

  81. ͸͍

  82. ͔͜͜Β༨ஊ εϥΠυͰݟͯΔਓ޲͚ ͕࣌ؒ༨ͬͨΒ࿩͠·͢

  83. ͜͏͍ͬͨΠϕϯτۦಈͷͳʹ΍Βྫ • reactPHP • areys • swoole

  84. reactPHP • https://github.com/reactphp/http • ఀ଺͍͕ͯͨ͠ɺ෮׆ʂ • …ͱ͓΋͍͖΍ɺਖ਼݄ऴΘͬͨΒ·ͨࢭ·ͬͨ • ͱ͸͍͑ɺhttpd͍ͩͿྑ͘ͳͬͨɻͪΐͬͱલ·Ͱ͸ɺʮॻ ͘͜ͱ΋Ͱ͖ΔΑʂʯͱ͍͏αϯϓϧίʔυͬΆ͍ײͩͬ͡

    ͨɻ • POSTͷ࣮૷͕؆қ͗͢Δ౳͕͋ͬͨ
  85. reactPHP ͸ PSR-7ରԠ • PSR-7ରԠͰ࣮૷͞ΕͨͷͰɺPSR-7ରԠͷFW͕৐Δʂ • …ͱ͍͏ͷ͸ӕͰ͢ɻଟ͘ͷFW͸άϩʔόϧΫϦʔϯͰͳ͍ (ಛʹɺηογϣϯͳͲ) • ଟগؾΛ͚ͭΕ͹͍͚Δ

    • PSR-7ඇରԠͰ΋Laravel(ྫ:mnvx/laravel-reactphp)΍ Symfony͸όΠϯσΟϯά͕͋Δʢ͕…ʣ
  86. ͦͷଞ • process manager͸ແ͍ͷͰɺӡ༻ʹ͸ผ్ systemd,supervisord,daemontoolsͳͲΛ࢖͏ • Α͘΋ѱ͘΋γϯϓϧ • ʮߴ଎ʯͱ͍͏ͷ͸ӕͰ͢ɻC֦ுͷeventͳͲΛ͍Εͯɺಛఆ ͷ༻్Ͱɺ஫ҙਂ͔͚͘͹ʮ͸΍͍ࣄ΋͋Δʯͱࢥ͏

    • ΠϕϯτۦಈηʔϑͳίʔυΛॻ͘ͷ͸݁ߏ͍ͨ΁ΜɺಛʹDB ઀ଓͱ͔ɻ
  87. aerys • https://github.com/amphp/aerys • amPHPͰ࣮૷͞Εͨhttpd • process manager͕͋Δʂ • PSR-7ͳʹͦΕ͏·͍ͷʁ(ಠࣗͷreq,res)

    • ݁ߏ׆ൃ
  88. • 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
  89. • άϨʔεϑϧϦελʔτ • ϓϩηεϚωʔδϟʢϫʔΧ਺มߋͳͲʣ • Unix domain sock • ࣮ߦϢʔβʔมߋ

    • Ϧόϓϩ • ηογϣϯʢRedisʣɺCookie • ͔ͳΓϓϩμΫγϣϯϨσΟײ͋ΔʢݸਓͷײͰ͢ʣ
  90. <?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);
  91. swoole • https://github.com/swoole/swoole-src • จ۟ͳ͠ʢʁʣͷproduction readyʂʢςϯηϯτ͕࣮༻͠ ͍ͯΔʣ • high performance

    for PHP. • த՚+C֦ுύϫʔͰ̎̌̌ສഅྗʢʁʣ • ͪΌΜͱߋ৽͞ΕͯΔʂ͍͢͝ʂʂ
  92. • ӳޠυΩϡϝϯτ͔ͳΓ੔උ͞Εͨʢͪΐͬͱલ·Ͱதࠃޠ͹ ͔Γͩͬͨʣ • Linux,OSX,WindowsͰ΋ಈ͘ʢͱॻ͍ͯ͋Δ͕ͪΐ͍ඍົʣ • Ϗϧυ͸ָʢґଘ͕ͳ͍ʣ • IDE helper΋͋Δ

  93. ׬શʹ༨ஊͳSwooleͷ͍͢͝ͱ͜Ζ • ͳΜͱʂʂʂPHPͳͷʹʂʂʂCoroutineͱChan(nelʣ͕͋ ΔʂʂʂGo͔Αʂʂʂ

  94. $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; } });
  95. • ͳ͓ɺOSXͩͱڍಈ͕͓͔͔ͬͨ͠ɻ·ΕʹηάΔɺsleep͕ ࢭ·Δɺcoroutine͕ฒ૸͠ͳ͍ɻ • ʢͨΊͨ͠ͷ͕ͪΐͬͱલͳͷͰ΋͏࣏ͬͯΔ͔΋ʣ • LinuxͩͱͪΌΜͱ͏͘͝งғؾ • ඇಉظ͚ͩͰ͸ͳ͍ɺϚϧνεϨουϚϧνϓϩηεͰ࢖͑Δ ϩοΫ΍mmapɺ҆શͳϩʔΧϧredisΈ͍ͨͳtableɺϓϩη

    εϚωʔδϟ΋͋Γ…ຊՈʹऔΓࠐ·Εͯ͘Εʂʂʂʂ • ਖ਼௚ɺ֦ு͞Ε͗͢Ͱ͸
  96. • HHVMͱ͕ͪ͏ํ޲ੑͰʢPHPͷ··ʢʁʣͰʣਐԽ͍ͤͯͬ͞ ͍ͯΔΑ͏ʹΈ͑ͯɺݸਓతʹ͸޷ײ͕͋Δ • ΈΜͳ͓ࠔΓʹͳΔDNSϦκϧόʢͷඇಉظͷ΍ͭʣ·Ͱ૷උ • ʮPHPʹcoroutinͳ͍΍Ζʯʮͤ΍ͳʯ • ࣮ࡍ݁ߏߴ଎ͩ͠ɺເͱϩϚϯ͕͍͢͝

  97. ͜ΕͰؾܰʹwaitΛ͔͚Δ͜ͱ΋Ͱ͖Δ͠ɺདྷ೥ͷISUCON͸͜Ε ͩʂʢҧ ʢISUCON༑ୡืू͍ͯ͠·͢ʣ

  98. ΍ͬͨʂ͜ΕͰ͍͚Δʂʂ • C֦ுͳΜͩΑͳ͋… • ʮʢ͜͜Ͱ͍͏ʣେ౷Ұײʯ͸ബ͍ʢผʹ౷Ұ͠ͳ͍͍͚ͯ͘ Ͳʣ

  99. ࠶ܝʣଞͷݴޠ͸ɺC֦ு͸ʮlibʯଆ ʹೖΔ • phpͩͱɺΠϯετʔϧͨ͠phpͷԼͷmodulesʹ͸͍Δ • php.iniʹextensions=hoge.so • Ͱ΋·͋ɺdlؔ਺΍࣮ߦ࣌Ҿ਺͔ͭ͑͹͍͍ΜͩΑͶʂ • ͱ͍͏͜ͱͰɺಥવͰ͕͢ʮ΄͔ͷݴޠͷC֦ுͷී௨ʯΛճऩ

    ͢Δ͜ͱ͕Ͱ͖·ͨ͠Ͷɺʢಥવͷճऩʣ
  100. ʢISUCON஥ؒืूதͰ ͔͢ΒͶʁʣ

  101. ͜͜·Ͱ༨ஊ

  102. ͸͍

  103. ࢲʮͲ͏Ͱ͔͢ʁhttpdʹͳΓ·ͨ͠Αʯ ʁʮϑΝΠϧ͕ͨ͘͞Μ͋Δͷ͕ͳ͋…ʯ ࢲʮͳΜͩͱʯ

  104. ̍ϑΝΠϧʹ͠ͳ͚Ε͹ʢ࢖໋ײʣ • ΍ͬͨΔ͔ʂ

  105. ౷Ұ͍ͯͧ͘͠ʂ

  106. Phar • PHPͷίʔυ΍σʔλΛύοΫͰ͖Δ΋ͷ • composer.phar͸͝ଘ஌Ͱ͠ΐ͏ • file_get_contents΍fopenʹphar://ʙΛ౉͢ͱத͕ݟΕ Δ • stubʹmainతͳ΋ͷΛηοτ͢Ε͹ɺpharϑΝΠϧΛ௚઀

    phpͰ࣮ߦͰ͖Δ • php hoge.phar
  107. pharͷ࡞Γํ • boxΛ͔ͭ͏ͱ௒؆୯ • https://github.com/box-project/box2 • ʮpharΛͭ͘Δͷ͸໘౗ͳͷΛղܾ܅ʯ • box.jsonΛॻ͚ͩ͘ʂ •

    ͪΌΜͱComposerͰ͍Εͨ΋ͷ΋ಈ͘
  108. ͱΓ͋͑ͣɺ͖ͬ͞ͷ reactPHPͰ࡞ͬͯΈΔ

  109. box.json { "directories": ["htdocs","lib","templates","vendor"], "files": ["config.php","main.php"], "main": "main.php", "output": "react_tinitter.phar",

    "stub": true }
  110. $ php -d phar.readonly=false ~/bin/box.phar build Building... • -d phar.readonly=false͸σϑΥϧτͰ͸Pharͷʮॻ͖ࠐ

    Έʯ͸ېࢭ͞Ε͍ͯΔͷͰࢦఆɻphp.iniͰ΋͍͍͚Ͳͬͪ͜ ͷ΄͏͕ૣ͍ΑͶ
  111. • ͔ͳΓ͔͔࣌ؒΓ·͢ $ time php -d phar.readonly=false ~/bin/box.phar build Building...

    real 4m13.202s user 1m51.980s sys 1m44.934s
  112. real 4m13.202s

  113. • ʮ…͖ͬͱxdebug͕͸͍ͬͯΔ͔Βͩ…ʯ • ʮ֦ுΛɺ-dͰ௥Ճ͸Ͱ͖Δ͕ɺ࣮ߦ࣌ʹ࡟আ͸…ʯ • ʮ….gitҎԼ·ͰύοΫ͞Εͯͳ͍͔͜Εʁʁʯ

  114. ͔͠͠ɺੈք͸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
  115. Phar::interceptFileFuncs(); • ࠷ߴؔ਺file_get_contents΍fopenͳͲΛԣऔΓ͠·͢ • ͕͢͞C֦ுɺͦ͜ʹγϏΕΔಌΕΔ • /Ͱ࢝·Βͳ͍ʢ૬ରύεʣ৔߹ɺݱࡏͷPhar಺͔ΒಡΉ • __DIR__΋͔ͭ͑Δ(phar:///tmp/example.phar/bin) •

    ʮେମʯͳΜͱ͔ಈͧ͘ɻ • reactͷ੩తϑΝΠϧ഑৴ΞυΦϯ΋ಈ͘
  116. ͔͠͠PDO͕͏͔͝ͳ͍ $ php react_tinitter.phar Slim Application Error: Type: PDOException Code:

    14 Message: SQLSTATE[HY000] [14] unable to open database file
  117. Phar::mount() • Phar֎ͷϑΝΠϧ΍σΟϨΫτϦΛ͔͋ͨ΋Phar಺ʹ͋Δ͔ͷ Α͏ʹࢀর͢Δ͜ͱ͕Ͱ͖Δʢલड़ͱ૊Έ߹ΘͤΔࣄʹͳΔʣ • ྫɿpharͷ֎ʹ͋Δsqlite.dbΛɺதʹ͋ΔΑ͏ʹ͢Δ Phar::mount( 'sqlite.db', dirname(Phar::running(false)).'/sqlite.db' );

  118. • ͜ͷ࣌ɺ__DIR__͕Phar಺෦ʹ͔Θͬͯ͠·͏ͷͰ஫ҙ • Α͘΍ΔPDO("sqlite:".__DIR__."/sqlite.db")Έ͍ͨ ͳͷ͸ɺ૬ର౳ʹॻ͖׵͑·͠ΐ͏

  119. Phar::running() • Pharʹ͠ͳ͍ͱಈ͔ͳ͍ͱ͔ແཧͳͷͰɺPharԽ͞Ε͍ͯΔ͔ ൱͔Λ஌ΔͨΊʹ͔ͭ͏ • __FILE__ Έ͍ͨͳ΋ͷ͕ฦ͞ΕΔɺ֎ͳΒfalse • Ҿ਺ʹfalseͰɺPharࣗମͷύεΛฦ͢ $isUnderPhar

    = (Phar::running()!=="") ;
  120. ͱ͍͏͜ͱͰ • ϒʔτετϥοϓʹͳΔmain.phpͷઌ಄ʹॻ͘ <?php if(Phar::running()!==""){ // under phar Phar::mount('sqlite.db', dirname(Phar::running(false)).'/sqlite.db');

    Phar::interceptFileFuncs(); } require "vendor/autoload.php"; // ...
  121. Ͱ͖ͨʂ • DEMO • ͯ͠΋ɺผʹ୅ΘΓө͑͠ͳ͍͔Βͳ…

  122. ίʔυ͕େ౷ҰͰ͖ͨʂ

  123. ͸͍

  124. ࢲɿʮ͜ΕͰ̍ϑΝΠϧʹͳͬͨʂʯ ʁɿʮ͑ͬɺίʔυͱόΠφϦͱผ͡ΌΜʯ ࢲɿʢ΋͸΍ͦΕ͸೉บͳͷͰ͸ʁʁʁʁʣ

  125. சੜɺ͞Βʹ౷Ұͩʂʂ • ͱ͍͏͜ͱͰͭͳ͍͖͛ͯ·͠ΐ͏

  126. ग़མͪʣ΍ͬͨʂେ౷Ұͩʂʂ $ 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͕͸͍ͬͨͧʂʂ
  127. ղઆ cat php main.php > one-pack-php ! [PHPόΠφϦ] + [PHPίʔυ]

    = [PHPόΠφϦ|PHPίʔυ]
  128. $ ./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͍ͯ͠Δ
  129. ʮ΍ͬͨͥʂ౷Ұͩʂʯ

  130. օ͞Μͷײ૝ • ʮ͏ͦͩΖʂʁʯ • ʮ͏ͦͰ͸ͳ͍ʯ

  131. օ͞Μͷײ૝̎ • ʮਖ਼ؾͷࠫଡͰ͸ͳ͍ʯ • ʮ͔ͨ͠ʹʯ

  132. ී௨ͷͨΊʹ͸ඇৗࣝΛ͠ͳ͚Ε͹…ʢʣ

  133. ΍ͬͨʂ͜ΕͰউརʂʂ • ͱ͓΋͍͍͕ͨ…

  134. ͨΜͳΔPHPιʔεͳΒಈ͕͘… • phar͸fsʹ͓͔Ε͍ͯͳ͍ͱopenͰ͖ͳ͍ • ʢphp ext/pharͷιʔεΛΈΔͱ…ʣ • ͙͙͙

  135. ͦͷ͜Ζࢲ͸ YAPC::Okinawaͷҝɺ ԭೄʹ͍ͨ

  136. • ʮ…͏ͬ͢Βؾ͍͍͕ͮͯͨɺ͜Ε͸ແཧͳͷͰ͸…ʯ • (ԭೄ໊෺ίʔώʔ๐੝ΛҿΉ) • ʮ͍ͬͯ͏͔ɺfs͕ͳ͍؀ڥͳ͍΍Ζɺfs͔͓ͭ͏ʯ

  137. • ͱ͍͏͜ͱͰਖ਼ؾʹͳΓPharͱPHP࿈݁Ҋ͸ϘπʹͳΓ·ͨ͠ • ʢʮ౷Ұʯͷֶͼ͸͋ͬͨʣ • ʢ؇ืɿΑ͍ಀ͛ಓʣ

  138. ୅Ҋ bash ࣗݾղౚʹΑΔ࣮ߦ • ͪ͜Β͸ඇৗʹ༝ॹਖ਼͍͠खஈͰ͢Ͷ • php, codeΛղౚ࣮ͯ͠ߦ

  139. #!/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
  140. #!/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
  141. Ͱ͖ͨʂ • demo

  142. ΋͠࢖͏ةಞͳਓ΁ͷ஫ҙ • ্ͷίʔυͷtar͸gnu tarͰ͢ɺosxͰ΍ΔͳΒbrewͰ͍Ε ΔͳΓ͍ͯͩ͘͠͞ • ʢ͋Δ͋Δ…ʣ • sqlite.db·ͰಥͬࠐΉͱɺ౰વ࠶ىಈͷͨͼʹר͖໭Γ· ͢ɻMysqlͱ͔࢖͍ͬͯͩ͘͞ɻ

  143. ʮ͍ͭʹʂେ౷Ұʂͩʂʯ

  144. ͸͍

  145. ࢲɿʮ͜ΕͰͲ͏Ͱ͔͢ʂʯ ʁɿʮ͍ͬͯ͏͔ɺPHP͸Dockerͱ͔ʹͯ͠΋ΠϝʔδαΠζͰ ͔͗͢ΔΘɺPHP͸͜Ε͔ͩΒʯ • ʢ͍ͬͯ͏͔͖ͬ͞ͷͰಥવPHP͕ϫϯόΠφϦͰίϐʔͯ͠Δ ॴ͕෍ੴͰ͢Ͷʣ

  146. சੜখͯ͘͞͠΍Δʂʂ • ੎͍Ͱɺ̍όΠφϦͰɺখ͍͞PHPΛͭ͘Δ • ʢಥવͷϧʔϧɿҰݸͷϑΝΠϧͰ·ͬ͞Βͳ؀ڥʹ΋͍ͬͯ ͬͯ͏͚͝͹OKʣ

  147. ઌऔΓΦν৘ใ $ ./configure --disable-all --enable-mbstring --enable-json $ make all $

    cp sapi/cli/php /path/to/php
  148. Ͱ͖ͨʂʂ • ʮMac΍LinuxͰ͸͍͚ͨΑʂʯ • ʮ͍΍…Զ͸Docker͔ͩΒ…ʯ • ʮνοʯ

  149. alpineͰಈ͘࠷খͷPHPΛ࡞͍ͬͯ͘ • ຌ༱ʹUbuntuͩͱ1GB͘Β͍͋Δɺ͔ͨ͠ʹ͖ͼ͍͠ • ެࣜϨγϐͩͱ60Mbyte͘Β͍ • ͑ͬɺ͜ΕͰσΧΠͷʁ

  150. Φν ʢ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͕Ͱ͔͍ΜͩΑͳ͋…
  151. ݁Ռ $ 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
  152. miniphp 11.4MB php-7.2.2-cli-alpine3.7 62.5MB • ʮ11Mbyteͩͧɺ΋͏ΏΔͯ͘͠Ε…ʯ

  153. ͨͩɺ๻͸ผʹDockerΛ͔ͭΘͳ͍ͷͰ • ࣮ࡍʹ͜Μͳ͜ͱΛීஈ͸͠ͳ͍ • ͱΓ͋͑ͣ࡞ͬͨΜͩ

  154. ʢ͜ͷ݁Ռ͸·ͩ΋͍ͬͯͬͯͳ͍ͷͰɺଓ͖͕͋Δ͔͸Θ͔Γ· ͤΜʣ

  155. ͱ͍͏͜ͱͰɺ • PHP͕httpdʹͳΔΑ͏ʹͯ͠ • PHPΛϫϯόΠφϦʹͯ͠ • ࣗݾղౚܗࣜͰύοΫͯ͠ • ̍ϑΝΠϧʹ͢Δ͜ͱʹΑΓ •

    ଞͷݴޠͷਓ͕͍͏ʢʁʣʮී௨ʯͬΆ͍ʢಠࣗݟղʣφχΧ ͕Ͱ͖ͨ
  156. ʮ͜Ε͕ϫΠͷେ౷Ұ΍ʂʯ

  157. ! • ·ͱΊʹೖ͍͖ͬͯ·͢

  158. ·ͱΊ • ແ೉ʹapache+mod_phpɺ͋Δ͍͸nginx+php-fpmΛ࢖͍· ͠ΐ͏ • ͦΕͰ΋νϟϨϯδ͢Δਓɺͥͻ๻ͱ͓࿩͠·͠ΐ͏ • ʮདྷ೥͋ͨΓͷISUCONʹSwooleͰग़Δ༑ୡΛืू͍ͯ͠· ͢ʂʯ

  159. ʮԶ͸઴࢝͘Ίͨ͹͔Γ͔ͩΒͳɹ ɹ͜ͷ͸ͯ͠ͳ͘ԕ͍େ౷ҰΛΑ…ʯ (to be continued...) (࣭໰Ͳ͏ͧ) (ͳ͚Ε͹༨ஊ)