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
ハチャメチャに叩く
Search
uzulla
July 13, 2018
Programming
1.9k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ハチャメチャに叩く
【非公式】PHPカンファレンス 2018 関西 前夜祭
https://dbstudychugoku.connpass.com/event/92337/
uzulla
July 13, 2018
More Decks by uzulla
See All by uzulla
ALL CODE BASE ARE BELONG TO STUDY
uzulla
30
7.9k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
620
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
2.9k
似たもの同士のPerlとPHP
uzulla
1
320
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
240
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
350
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
240
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
3.4k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.6k
Other Decks in Programming
See All in Programming
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
320
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.2k
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
34k
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
900
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
430
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
270
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
1.1k
JIS keyboard support in Omarchy
lef237
0
150
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
120
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
820
Jetpack Compose Mechanisms
skydoves
3
860
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
190
Featured
See All Featured
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
610
Color Theory Basics | Prateek | Gurzu
gurzu
1
490
How STYLIGHT went responsive
nonsquared
100
6.3k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
460
We Have a Design System, Now What?
morganepeng
55
8.4k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
640
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
450
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
810
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
460
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
310
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Transcript
ϋνϟϝνϟʹhttp(s) ͰԥΓ͍ͨ
@uzulla
ઌSwooleͷΛ͠·͕ͨ͠ • https:/ /speakerdeck.com/uzulla/zui-jin- meruhuomukaitenaimeruhuomaniyoru-tiyotutodakebian-watuta- ying-phpfalsemeruhuomu-falseohua-fu-ti-zui-jin- swoolegatafalsesiidesu • ʢ͍…ʣ •
ʢuzulla swoole speakerdeckͰݕࡧʣ • ඇಉظɺcoroutineͷ͕͋·ΓͰ͖ͳ͔ͬͨͷͰ • ͦͷؔ࿈
ਓϋνϟϝνϟʹʢAPIͱ͔Λʣୟ͖͍ͨ • PHPͰͲΜͲΜୟ͖͍ͨ • Ϋϩʔϧ͍ͨͨ͠Ί • ྲྀߦͷϚΠΫϩφϯτΧͰࢁAPIΛୟ͘ඞཁ • շײΛಘΔͨΊ
• ͔͠͠PHPʮ͍ʯ(Β͍͠) !
• Կ͕͍͔ʁ! • httpʮऔಘ͢Δͪ࣌ؒʯ͕ࢧత • ྻͷಉظॲཧͰͦͷؒͳʹͰ͖ͳ͍ʂ " • ଞͷݴޠͰ؆୯ʹʢʁʣϚϧνεϨουʹͨ͠Γ͢Δʢཁ ग़య#ʣ
• ͔͠͠PHPϚϧνεϨουɺϚϧνϓϩηεΉ͔͍ͣ͠ ʢཁग़య#ʣ
Ͳ͏͢Δ͔ʁ • ඇಉظͩʂ • PHPͷඇಉظ݁ߏྺ࢙͕͋Δ(ओ؍) • ʢඇಉظI/OɺϊϯϒϩοΩϯάI/OɺଟॏԽI/Oͱ͔৭ʑ͋Δ ͕ɺ͜͜ͰҰॹͨ͘ʹඇಉظͱ͓͖ͯ͠·͢ʣ
ʮඇಉظʯͱʁ • I/OॲཧதʹϘʔͬͱͤͣɺଞͷ͜ͱΛΕΔ • ฒྻॲཧͰͳ͍ɺʢਅͷʣϚϧνεϨουͰͳ͍ • ͳΜΒ͔c֦ுΛೖΕͳ͍ͱCPUෛՙ͕ߴ͍ • ex: ev,uv,event,swoole
• ૉखͰ৮ΔͷେมͳͷͰϑϨʔϜϫʔΫ͕ॏཁ • ex: reactPHP,swoole,amp
None
None
None
None
None
༨ஊ curl_multi Ͱ͍͍ͷͰʁ • ࠷ॳʹʮNݸऔಘʯΈ͍ͨʹͳΔͷͰɺ̍ͭऴΘΓ࣍ୈҰͭى ಈͱ͔Ͱ͖ͳ͍ • ༻్ʹΑΔ͕ɺྫ͑ΫϩʔϥͰඞཁ • selectͷѻ͍͍͠…
• ʢͦͦcurl_* ࣗମ͕͍͠ʣ • ʢͲ͜ʹͰೖ͍ͬͯΔʢʁʣͷ࠷ߴʣ
ʮͱ͍͏͜ͱͰswooleͰඇಉظͩʂʯ • ຺བྷলུ͠·͢ɻ • ʮͳͥPHPͳͷ͔ɺదࡐదॴ͕ඞཁͰʁʁʯ • ʮࠓPHPҎ֎ͷ͔ͯͨ͠͠ͳ͍Ͱ͠ΐ…ʯ
swooleʹ͓͚Δهड़ํࣜ • callbackํࣜ • coroutineํࣜ
• callbackํࣜ • ΠϕϯτۦಈΒ͍͠ॻ͖ํ • JSͬΆ͍ • ຊདྷ͕ͪ͜ΒͳͷͰɺݫີʹௐ͍͢͠ • ωετஅ͕૿͑ΔͷͰগʑಡΈͮΒ͍
• coroutineํࣜ • ී௨ͷίʔυͬΆ͍ɺಡΈ͍͢ɺָ • (PHPͷ) δΣωϨʔλͬΆ͍ • ͪΐͬͱͨ͠ແବ͕Ͱ͖͍͢ •
৭ʑӅṭ͞Ε͍ͯΔͷͰɺٯʹ࣮ߦͮ͠Β͍͜ͱ • ࠓճͪ͜Β
• swoole࠷ۙcoroutineํࣜਪ͠ • swoolego()Λ͔ͭ͏ͱɺઐ༻ڥʢΠϕϯτϧʔϓͳͲʣ֎Ͱ ίϧʔνϯΛಈ͔ͤΔ • ʢͷͰָɻׂ͕͜͜ͱॏཁͳͷ͕ͩɺൺֱʹͳΔ͠આ໌͕ ͘ͳΔͷͰলུʣ
coroutineͷྑ͍ͱ͜Ζ • ;ͭʔͷίʔυͰɺAPIDBΞΫηεΛ͍͔ͭ͘ॱ൪ʹߦ͏ • coroutineී௨(ྻ)ʹॻ͚Δ • callbackํࣜωετ(ؔͰׂ)͠ͳ͚ΕͳΒͳ͍ • PromiseΛ͔ͭ͑ฏୱʹͰ͖Δ͕ɺείʔϓͷׂ͞Ε Δ
ͱ͍͏͜ͱͰαϯϓϧίʔυ • coroutineํࣜ • ʮwhileͰΔͷɺͲ͏ͳͷʁʯ ʮsleepΛௐ͢Ε࣮༻Ͱ͠ΐ…ʢͲ͏͔ͳʁʣʯ
• ͓ࢼ͢͠Δਓͪ͜Β͔ΒͲ͏ͧ • https:/ /github.com/uzulla/sample-co-get
<?php // Ұൠతͳྻऔಘίʔυ const MAX_REQ = 10; // نఆॲཧ $req_num
= 0; while (1) { echo "."; // نఆॲཧΛ͑ͨͷͰऴྃ if ($req_num >= MAX_REQ) { break; } // औಘ $req_num++; $_ = file_get_contents("http://example.jp"); }
• 1req2ඵ͔͔ΔAPIΛ10ճऔಘͩͱ… real 0m20.199s user 0m0.089s sys 0m0.067s
<?php // coroutineͰ͔͍ͯΈΔ go(function () { $now_worker_num = 0; $req_num
= 0; while (1) { echo "."; co::sleep(0.001); // εέδϡʔϥͷͨΊʹ // نఆॲཧूΛ͑ͨͷͰऴྃ if ($req_num >= MAX_REQ) { break; } // ىಈதͷίϧʔνϯ͕نఆʹୡ͍ͯ͠ͳ͚ΕՃىಈɺ // ʢنఆϫʔΧʔͳΒىಈͤͣɺϧʔϓઌ಄ʣ if ($now_worker_num >= MAX_WORKER_NUM) { continue; }
// while (1) { // ... // go()ͷΫϩʔδϟ͕ίϧʔνϯͱͯ͠εέδϡʔϥʹొ go(function ()
use (&$now_worker_num, &$req_num) { $req_num++; $now_worker_num++; $http = new \Swoole\Coroutine\Http\Client( "http://example.jp", 80); $http->get('/'); $_ = $http->body; $now_worker_num--; }); // ্هྃΛͨͣʹൈ͚Δ } });
real 0m4.187s user 0m0.267s sys 0m0.523s
• 1req2ඵ͔͔ΔAPIΛ10ճऔಘ͢Δͷʹ • ʢಉظʣ20ඵ->ʢඇಉظʣ4ඵ • ಉ࣌5ଓͩͱ̎ճ • ಉ࣌10ʹͳΒҰׅͰऴΘΔͷͰ̎ඵʹ • ʢ…ͳΔ͜ͱ͋Δʣ
coroutineཧղצॴ • go()ͰίϧʔνϯΛ࡞ͯ͠ʮޙͰ࣮ߦϦετʯʹՃ͠ʢεέ δϡʔϧ͞ΕΔʣɺޙͰ࣮ߦ͢Δ • ઐ༻ʹ࡞ΒΕͨؔҎ֎ඇಉظʹͳΒͳ͍
εέδϡʔϧ…ʁ • ֓೦ਤͰͬ͘͟Γઆ໌͍ͨ͠
None
None
None
None
None
None
None
• ʮεέδϡʔϧͬͯΫϩʔδϟΛฒସ͍͑ͯΔ͚ͩͳͷͰ ʁʯʮ͜͜Ͱ͋Δҙຯਖ਼ղͰ͢ʯ • (ࠓճset/getDeferͷ͠·ͤΜ) • ʢͪΌΜͱཧղ͢ΔͨΊʹίʔυΛಡΉͳΒɺreactPHPͳͲͷ ίʔυൺֱతಡΈ͍͢ʢSwooleCͳͷͰ…ʣʣ
• Ͳ͔͜ΒͰࣗ༝ʹεΠον͞ΕΔ༁Ͱͳ͍ • ओʹIOsleepͳͲɺͯ͠ҙຯ͕͋ΔॴͰ͞ΕΔ • ͦ͏͍͏;͏ʹSwoole͕औΓ͍ͬͯΔ
• JSΈ͍ͨʹؔ୯ҐͰࣗಈతʹΓସ͑͞Εͳ͍ͷͰҙ • ʮͳΜ͔ίϧʔνϯ͕ಈ͔ΜʂແݶϧʔϓʂϩοΫʂʯͱ͍ ͏࣌େମ͜Ε • ׳ΕΔ·Ͱࢥͬͨ௨Γͷ࣮ߦλΠϛϯάʢεέδϡʔϦϯ άʣʹͳΒͳ͍͜ͱ͋Δ • ඞཁͳΒɺखಈͰco::sleepͳͲΛೖΕͨΓ͢Δ
• ׳ΕΔ·ͰʮͳΜͰಈ͔ͳ͍Μͩ…ʯͱࢥ͏͜ͱ ->׳ΕΑ͏ʂ
·ͱΊ • ʮඇಉظ͋Μ·Γා͘ͳ͍ʯ • γϯϓϧʹॻ͖͘͢ಡΈ͍͢ͷ͕ʢSwooleͷʣ Coroutineʢओ؍ʣ • ͲΜͲΜAPIͳͲΛୟ͍ͯճΓ·͠ΐ͏ʂ
ຊͷ(?)·ͱΊ • file_get_contentsͰेͳΒɺͦ͏͠·͠ΐ͏ • ʮfile_get_contentsͰ͕ͨΓͳ͍༻్ͱ…͏͝͝…ʯ • ʮඇಉظͰ͏·͘ΕඵؒXXXXճୟ͘͜ͱເͰͳ ͍ʂʯ • →
ࣄ݅ʹͳΔ • ʮඇಉظͱ͔ɺ୭͕ϝϯς͢ΔΜͩ…ʯ • ʢ ચ ҭ͍ͯ͜͠͏ʣ
ࠓ͞ͳ͔࣮ͬͨࡍʹϋνϟϝνϟʹୟͨ͘ Ίʹॏཁͳॴ • DNSΩϟογϡɺkeep-aliveɺλΠϜΞτ&ϦτϥΠɺಈతε ϩοτϦϯάɺchanͳͲͰͷσʔλड͚͠ɺDefer • ʮຊʹඇಉظ͕ඞཁͳॴͱͲ͔͜ʁʯ • ॏ͍݁Ռॲཧ͕ඞཁͳΒϚϧνίΞ͕׆͔ͤΔͷͰϚϧνϓ ϩηεͷ΄͏͕ྑ͍
• ʮϚϧνϓϩηεʴඇಉظͩʂʯʮγϯϓϧͱ…ʯ
go()͝ਗ਼ௌ͍͖ͨͩ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ɻ
• ͕࣌ؒ༨ΕҎԼ
coroutine͕ಡΈ͍͢ɺͱʁ • ʢҎԼ࣮ࡍʹಈ͔͍ͯ͠ΔίʔυͰͳ͍Ͱ͕͢ʣ
go(function () { $http = new Co\Http\Client("http://example.jp", 80); $http->get('/api.json'); $data
= json_decode($http->body); $id = $data[0]['id']; $http->get('/api.json?id='.$id); $data = json_decode($http->body); $child_id = $data[0]['child_id']; $http->get('/api.json?child_id='.$child_id); $data = json_decode($http->body); echo $data['title']; //-> });
$client = new Swoole\Http2\Client("example.jp", 80); $client->get("/", function ($o) use($client) {
$data = json_decode($o->body); $id = $data[0]['id']; $client->get("/api.json?id=".$id, function ($o) use($client) { $data = json_decode($o->body); $child_id = $data[0]['child_id']; $client->get("/api.json?child_id=".$id, function ($o) use($client) { $data = json_decode($o->body); echo $data['title']; //---------> } } });
3ճϦΫΤετΛͳ͛Δͱ… # coro //-> (1Πϯσϯτ # cb //---------> (3Πϯσϯτ
• ී௨ɺ͍͔ͭ͘ͷAPIDBΞΫηεΛॱ൪ʹߦ͏ • coroutineී௨(ྻ)ʹॻ͚Δ • ίʔϧόοΫํࣜωετ(ؔͰׂ)͠ͳ͚ΕͳΒͳ͍ • PromiseΛ͔ͭ͑ฏୱʹͰ͖Δ͕ɺείʔϓͷׂ͞Ε Δ
see also • https:/ /wiki.swoole.com/wiki/page/p-coroutinehttpclient.html • https:/ /github.com/swoole/swoole-src/tree/master/examples/ coroutine •
https:/ /wiki.swoole.com/wiki/page/752.html • https:/ /wiki.swoole.com/wiki/page/784.html • https:/ /github.com/eaglewu/swoole-ide-helper • https:/ /www.swoole.com/ • https:/ /www.swoole.co.uk/docs/modules/swoole-async-http-client