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
PHPer人生、一度はフレームワークを作っておこう!
Search
uzulla
April 16, 2016
Programming
15
21k
PHPer人生、一度はフレームワークを作っておこう!
PHPカンファレンス北海道 2016 発表資料
20160416
uzulla
April 16, 2016
Tweet
Share
More Decks by uzulla
See All by uzulla
ALL CODE BASE ARE BELONG TO STUDY
uzulla
30
7.6k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
540
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
2.1k
似たもの同士のPerlとPHP
uzulla
1
290
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
220
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
320
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
230
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
3.1k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.4k
Other Decks in Programming
See All in Programming
おれのAgentic Coding 2026/03
tsukasagr
1
120
[PHPerKaigi 2026]PHPerKaigi2025の企画CodeGolfが最高すぎて社内で内製して半年運営して得た内製と運営の知見
ikezoemakoto
0
310
見せてもらおうか、 OpenSearchの性能とやらを!
shunta27
1
150
The free-lunch guide to idea circularity
hollycummins
0
390
AIと共にエンジニアとPMの “二刀流”を実現する
naruogram
0
100
脱 雰囲気実装!AgentCoreを良い感じにWEBアプリケーションに組み込むために
takuyay0ne
3
420
ファインチューニングせずメインコンペを解く方法
pokutuna
0
220
ロボットのための工場に灯りは要らない
watany
12
3.2k
Strategy for Finding a Problem for OSS: With Real Examples
kibitan
0
120
Xdebug と IDE による デバッグ実行の仕組みを見る / Exploring-How-Debugging-Works-with-Xdebug-and-an-IDE
shin1x1
0
270
ポーリング処理廃止によるイベント駆動アーキテクチャへの移行
seitarof
3
1.3k
今年もTECHSCOREブログを書き続けます!
hiraoku101
0
200
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
300
How to Talk to Developers About Accessibility
jct
2
160
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
120
Imperfection Machines: The Place of Print at Facebook
scottboms
269
14k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
230
Technical Leadership for Architectural Decision Making
baasie
3
300
Large-scale JavaScript Application Architecture
addyosmani
515
110k
What does AI have to do with Human Rights?
axbom
PRO
1
2.1k
30 Presentation Tips
portentint
PRO
1
260
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
500
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.8k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
120
Transcript
PHPerਓੜɺ ҰϑϨʔϜϫʔΫΛ࡞͓ͬͯ͜͏ʂ » at: PHPΧϯϑΝϨϯεւಓ » date: 20160415 » speaker:
uzulla
ʢҙɺຊεϥΠυޱ಄Ͱ͑ͨࣄ͕͔ͳΓൈ͚͍ͯ ·͢ʣ
"who are you ?" UZULLA PHPer ʮ౦ژํ໘͔Β͖·ͨ͠ʯ
PHPerਓੜɺ ҰϑϨʔϜϫʔΫΛ ࡞͓ͬͯ͜͏ʂ
201Xʂ ੈքنͷԌʹแ·Εͨʂʂ
» ʮҪށރΕɺാߥΕɺ͋ΒΏΔ$_GETઈ໓ͨ͠ ͔ʹݟ͑ͨɻ ͕ͩɺΦϨΦϨϑϨʔϜϫʔΫࢮ໓ ͍ͯ͠ͳ͔ͬͨ…ʯ
» ʮ͕͞ΕʂಓΛ͚͋Ζʙʂʯ » ʮʢ༗໊FWʣ༷ͷ͓௨Γͩʙʂʯ » ʰ΅͘ϑϨʔϜϫʔΫ࡞Γ·ͨ͠ʈʈʱ » ʮԚফಟͩʙʙʂʂʯ » ʰΪϟʔʂʂʂʱ
» ʮΘԼ࠲͠Ζʂʂফಟ͞Ε͔ͯ͑ʔʔʂʂʯ
ʢօ͞Μ͍͖ͭͯ ͍͚ͯͨͩͯ· ͢ʁʣ
» ཱͳFW͕૿͑ͨݱࡏɺϚοτͳFWΛΘͳ͍ ͜ͱ(ৗࣝతPHPerͱͯ͠ͷ)ࢮΛҙຯ͢Δͷͩɺί ϫΠʂʂ » ΦϨΦϨϑϨʔϜϫʔΧʔΦϨΦϨङΓʹૺΘ͵Α ͏ɺଉΛͻͦΊɺެʹ͢Δ͜ͱͳ͘ɺΦϨΦϨϑϨ ʔϜϫʔΫΛѪͰΔͷͰ͋ͬͨ…ɻ
» ͔ͯ͘͠ʮΦϨΦϨϑϨʔϜϫʔΫਓޱʯݮগ͠ɺ ҰΦϨΦϨͨ͜͠ͱͷͳ͍ඇΦϨΦϨਓͷ૿Ճ Λࢲײ͍ͯ͡Δ… » ʮڐͤΜʂΦϨΦϨϑϨʔϜϫʔΫѪՈͱͯ͠அ ݻઓ͍͍ͨʂʢݸਓͷײͰ͢ʣʯ » ͱ͍͏ͷ͕ɺ͜ͷτʔΫͷΞϯάϧͰ͢
·ͣ࠷ॳʹɺࠓࢲ͕ͲΕ͘ Β͍ఢΛͭ͘Δͷ͔͓ͬͯ ͖͍ͨΜͰ͕͢ɺ » օ͞Μ » ʮΦϨΦϨͬͯͳʹʁʯͰ͔͢ʁ » ʮҰΦϨΦϨʯͰ͔͢ʁ »
ʮωόʔΦϨΦϨʯͰ͔͢ʁ » ʮҰੜΦϨΦϨʯͰ͔͢ʁ
ʮͳΔ΄Ͳʯ » Ͱຊʹೖ͍͖ͬͯ·͢ɻ
FWΛ࡞Δલʹ FWͱͳΜͳͷ͔
ϑϨʔϜϫʔΫͱʁ Ŗ PHPͰʮΣϒΞϓϦέʔγϣϯ࡞࣌ʹཱͭϥ ΠϒϥϦͷηοτͱੈք؍ʴΤίγεςϜʯΛࢦ͢ࣄ͕ ଟ͍ - աڈಛʹલऀ͕ͩͬͨɺࡢࠓޙऀॏཁʹ - ʢҎޙɺFWͱུশ͠·͢ʣ
༗໊ͳFW Symfony, Laravel, Lumen, Slim Framework, Yii, PHPixie, FuelPHP, CodeIgniter,
CakePHP, ZendFramework, Phalcon, Nette, Silex, fatfree, limonade, DietCake, DietCube, Lithium, Aura, Ethna, etc. etc. 㙽ʹ֯ࢁ
ͬͱ͋Δʂଟ ͍ʂ » 2016-04-12ௐ » ͲΜͲΜ૿͑ͯΔ » (ແɺ͜ͷࣈϊΠζ ΛؚΉ) »
͜ͷ΄͔ʹɺηϯύΠ͔Β ͞ΕͨFWͱ͔͋ΔͰ ͠ΐ͏
తಛԽܕFW » ϒϩάΤϯδϯͷWordpress » CMSͷDrupal » ECαΠτͷECCUBE
FWΛ͏ཧ༝ - ੜ࢈ੑͷ্ - ܾ·ΓͬͨίʔυΛॻ͔ͣʹࡁΉ - ྑ͋͘ΔػೳϓϥάΠϯ͕͋Δ͜ͱ - ʮ੍ݶʯ͕Ͱ͖Δ͜ͱͰɺઃܭ͕͍͢͠ -
࣭ͷ্ - ϩδοΫʹूதͰ͖ɺ৽نίʔυྔΛݮΒͤΔ - ʮྑ͍ઃܭʯ͔Βဃͮ͠Β͘ͳΔ - ηΩϡϦςΟϗʔϧ͕উखʹຒΊΒΕ͍ͯΔࣄଟ͍ - େن։ൃͷجૅʹͳΓ͍͢ - νʔϜʹنΛཁٻ͍͢͠ - ʢେʣγοΧϦͨ͠υΩϡϝϯτ͕ଘࡏ͢ΔͷͰֶशɾڭҭ͍͢͠
ॴͰɺFWඞਢͳͷ͔ʁ » (PHP<=3ͷࣄলུ) » PHP4͔ΒɺPHPࣗମ͕ϑϨʔϜϫʔΫʹͳͬͨ » DBαϙʔτSessionαϙʔτ͋Δʂ » PHP͚ͩͰେମͷࣄॻ͚Δ »
͍·ͩʹ͜ͷૉͳੈքҰ෦Ͱ݈ࡏ
࣌ྲྀΕ… ʮৗࣝʯ͕มΘΔ
ʮPHPͰϧʔλʔ͕ඞཁͰʁʯ » ʢURLʹ͋Θͤͯॲཧ༰Λม͑Δʣ » PHPͰͷϧʔςΟϯάHTTPDͤ » form.php,confirm.phpͳͲʹผ͚Δݹ͖Ώ͔͍͠ε λΠϧʮμα͍ʯʮඇޮతʯ » SEOͩͳΜͩͰɺྑ͍ײ͡ͷURL͕ٻΊΒΕΔ࣌
» RESTʂRESTʂ
ʮςϯϓϨʔτΤϯδϯॏཁͩʯ » ςϯϓϨʔτΤϯδϯͱͯ͠PHPΞϧςΟϝοτ » ηΩϡΞ͞Λపఈ͢Δͷ͕Ή͔ͣ͗͢͠Δ <?php echo $_GET['foo']; ?> »
͜͜ʹ͍Δਓ͕ॻ͘ͱࢥ͑ͳ͍͕ɺοΧϦॻ͚ ͪΌ͏ » ʢBlogΧελϜҊ݅ͩͱׂͱݟΔ…ίϫΠ…ʣ » ʮੈքฏͷҝʹPHPͷྗΛ෧ҹ͢Δඞཁ͕͋Δʯ
ηΩϡϦςΟ͕ͯ͘ةݥ » ݱ༷ʑͳରࡦΛ͠ͳ͍ͱੈքฏ͕อͯͳ͍ » ಙؙຊجຊΫϦΞ͠ͳ͍ͱ͍͚ͳ͍ » PHP͚ͩͰ҆શͷͨΊͷΈօແ » ࣮Ͱ͖Δɺ͔͠͠ݸਓͷೳྗܹ͍ࠩ͠ »
htmlspecialcharsͱ͍͏ਖ਼࿐ؙ͔͠ͳ͍ਓ… » ਖ਼࿐ؙ͢Βͳ͍ݱ͠͠ݟ·͢ » FWΛਖ਼͔ͭ͑͘͠ɺ݁ߏԡ͑͞ࠐΊΔ(ཁग़య
ͦͷޙଓʑͱ » ʮ˓˓(ྫ:ORM)͕͋ΔͱΑͦ͞͏ʯʮ࡞Ζ͏ʯ » ͦΕΒϥΠϒϥϦ͕·ͱ·͍͖ͬͯɺ͍͔ͭ͠օ͕ ΔFWͱ͍͏ू߹ମʹ » ͞ΒʹFWؒɺݴޠؒͰݚᮎ͠ɺύΫϦ͋ͬͨΓͯ͠ ྑ͍͕Ͱ͖Δ »
ݱࡏҰൠਓΑ͍FWΛ૪͏Α͏ʹબͿ
ͳΜ͔Μ͋Γ » ͔ͯ͘͠ੈք༷ʑͳFWʹͭͭ·ΕɺΤϯδχΞ ฏͷʹΒͨ͠ͷͩͬͨ… » ʢͲͷFW͕͍͍͔બͿͷ͕େมͳࣄআ͘ʣ
!
Ͱͳ͍ » ͱ͍͏͜ͱͰɺFWͭ͘ΔͷͰͳ͘બͿͷ͕ݱ » ࣗͰۤ࿑͢Δඞཁͳ͍ » ඞཁͳ͍ͷʹ… » ΦϨΦϨϑϨʔϜϫʔΫΛ࡞ͬͯ͠·͏ਓ͍Δ »
ࢲͱ͔
ΦϨΦϨϑϨʔϜϫʔΫͱʁ » ੈͷதʹྑ͍FW͕ࢁ͋Δͷʹɺ Θ͟Θࣗ͟࡞ͯ͠͠·ͬͨFW » ओʹݸਓɺ৬ͳͲڱ͍ͱ͜ΖͰͷΈΘΕ͍ͯΔ ࣄ͕ଟ͍ » ʮΦϨΦϨFW߹๏Ͱ͢ʂʯ »
ͦͦଟ͘ͷ༗໊FWΦϨΦϨ͔Β࢝·ͬͨΖ͏
ΦϨΦϨͱϊοτΦϨΦϨͷҧ͍ʁ » ϑϨʔϜϫʔΫͱͯ҆͠ఆ͍ͯ͠Δʢയવʣ » օ͕ͦͷ༷ΛֶͯʢυΩϡϝϯτ͕උ » Ͱ͖ΕࢁͷͱɺݱͰࢼ͞Ε͍ͯͯ » Ͱ͖ΕσΩ͕Α͚ΕΑ͍ »
Ͱ͖Εຊޠॻ੶ͳΜ͔ͰͯΕ࠷ߴ » ʢఆٛͳΜͯͳ͍ɺͱ͍͏͜ͱͰ͢ʣ
ΦϨΦϨϑϨʔϜϫʔΫѪՈͷห » ʮΦϨͳΒͦ͜ΒͷFWΑΓྑ͍͕ͭ͘ΕΔʂʯ ʢ…ͳΜͯਓগͳ͍ʣ » ʮෳࡶͳFWʹख़ୡ͢ΔΑΓɺ࡞ͬͨํ͕ૣ͍ʯ » ʮ࡞ͬͯΔਓ͕ԣʹ͍Δ͔Βָʯ » ʮઌʑड͚ܧ͕Ε͖ͯͨ͜ͷFW࠷ߴʯ
» ʮOSSΛಋೖ͢ΔͷʹελϯϓϦϨʔ͕ࠈʯ » ʮ࡞ͬͯΈ͔ͨͬͨʯ
ΦϨΦϨϑϨʔϜϫʔΫʹର ͢Δ൷ྫ » ʮ࣭͕ѱ͍ʯ » ʮ΄͍͠ػೳ͕ͳ͍ʯ » ʮܧ͗͗ઃܭ͕ଟ͘ɺѲͮ͠Β͍ʯ » ʮηΩϡϦςΟʹ͕͋Δʯ
» ʮυΩϡϝϯτ͕ͳ͍͠ɺ࡞ͬͨਓ͕ୀ৬ͯ͠ࠈʯ » ʮPHPͷόʔδϣϯ্͕͛ΒΕͳ͍ʯ
ͲΕͬͱͳ͝൷ » ͔ͦ͠͠ΕΒ͋ΔॴͰͷ » झຯͷ୳ڀ৺ͷͨΊͳΒʹͳΒͳ͍ » ࡞ͬͯΈ͍ͨͳΒ࡞Δ͖ » ʢ͍ͬͯ͏͔࡞ͬͨ͜ͱͳ͍ͷʁϗϯτʹʁʣ »
ΦϨΦϨΛ࡞ΔࣄͰ͔Β͔ΘΕΔʢʁʣͷ ͓͔͍͠ʂ
ͱ͍͏͜ͱͰʢʁʣ » օ͞ΜΦϨΦϨϑϨʔϜϫʔΫΛ࡞Γ·͠ΐ͏ʂ » ͰɺҰͭͬͨ͘͜ͱ͕ͳ͍ਓ͍ͦ͏ » ͱ͍͏͜ͱͰɺຊΦϨʹΑΔΦϨΦϨϏΪφʔ ʹΉ͚ͨΦϨྲྀΦϨΦϨϑϨʔϜϫʔΫ࡞ྫΛ հ
ΦϨΦϨϏΪφʔ͚ใ » ΦϨΦϨϑϨʔϜϫʔΫͷ࡞Γํ » ඞཁͳͷ » ͋Δͱྑ͍ͷ » ͓͢͢Ίࢦ
ඞཁͳͷ » Δؾ » ࢀߟʹͳΔଞͷFW » ࠷ۙݟͨΦγϟϨͳTipsͱ͔ͷϒΫϚ
͋Δͱྑ͍ » ϝʔϧϑΥʔϜܝࣔ൘Έ͍ͨͳΞϓϦ » ීஈ͔͔͍͑ͯΔطଘFWʹର͢Δෆຬ » ΦϒδΣΫτࢦϓϩάϥϛϯάͷڭՊॻ » gitɺPHPStormͳͲ
͓͢͢Ίͳࢦ » ແܭը » ແ » ແςετ » ༗ݶ࣌ؒ
Ͱૣ… ͦͷલʹ
ҎԼͷࣄආ͚Α͏ʂ » ଞਓʹΘͤΔ » ࣄݸਓαʔϏεͷ͕͔͔Δॴʹ͏ » ͤ͞ΒΕͳ͍͜ͱΛޙչ͢Δ » ʢͦ͏͓͚ͯ͠ɺ୭൵͠·ͳ͍ʣ
Ͱ࡞ͬͯΈ·͢
ʮͳʹ͕͋ΕFW͔ͳʁʯ » FW͕ͲΜͳͷ͔օ͞ΜͬͯΔͱࢥ͍·͕͢ɺ ͲΜͳFWΛͭ͘Δ͔ͪΐͬͱߟ͑·͠ΐ͏ » ͱΓ͋͑ͣLaravelͷػೳҰཡΛݟͯΈͨ
Routing, Middleware, Controllers, Requests, Responses, Views, Blade Templates, Authentication, Authorization,
Artisan Console, Billing, Cache, Collections, Elixir, Encryption, Errors & Logging, Events, Filesystem / Cloud Storage, Hashing, Helpers, Localization, Mail, Package Development, Pagination, Queues, Redis, Session, SSH Tasks, Task Scheduling, Testing, Validation, Query Builder, Migrations, Seeding, Eloquent ORM,
ແཧ
ΦϨΦϨϑϨʔϜϫʔΫ࡞ ৺ಘΛࢥ͍ग़͢ » ༗ݶ࣌ؒʹऴΘΒͤΔ » ࠷ॳʹࢭΊॴΛܾΊ͓ͯ͘ » ྫʮ߹ܭ˓ҎʹͰ͖ΔΑ͏ʹ͢Δʯ » ྫʮ͋Δ࣮ʹ࣌ؒΜͩΒࠓճఘΊΔʯ
» ྫʮ͓खຊΛͰཧղग़དྷͳ͍ͳΒ࣍ճʹʯ
ϏΪφʔ·ͣϚΠΫϩϑ ϨʔϜϫʔΫ » ϧʔλʔʢίϯτϩʔϥʔʣ » ςϯϓϨʔτΤϯδϯʢϏϡʔʣ ͜ͷೋͭͰϑϨʔϜϫʔΫͱݴ͍ுΕΔͷͰΦτΫʂ
ϧʔλʔ » URLˍMethodͷఆύλʔϯΛొɾอ࣋ » ࣮ߦ࣌ʹରԠ͢ΔͷΛܾఆͯ͠ฦ͢
ςϯϓϨʔτΤϯδϯ » ϧʔλʔͰ࣮ߦͨ͠ίʔυͷ݁ՌΛܗ͢Δɺओʹ HTMLΛग़ྗ͢ΔͷʹΘΕΔͷ͝ଘ͡ͷ௨Γ » PHPࣗମ͕΄ͱΜͲςϯϓϨʔτΤϯδϯ
͜ͷೋ͚ͭͩͰ͢ΑɺͳΜ͔͙͢ʹͰ͖ͦ͏Ͱ͢Ͷʂ͍ ·͙ͭͬͯ͘͢Έ·͠ΐ͏ʂ
ͱ͍͏͜ͱͰ ͨ͠ͷ͕ίνϥ Ͱ͢
Ore frameworkരʂʂ » ΦϨϑϨʔϜϫʔΫʂ » ࡞̍͘Β͍ʂ » https://github.com/uzulla/Ore
ػೳ » ૉͳϧʔλʔ » '/post/:post_id' Έ͍ͨͳࢦఆҰԠͰ͖Δ » ૉࡐΛ׆͔ͨ͠ςϯϓϨʔτΤϯδϯ » ͍ͬͯ͏͔΄΅PHPͦͷ··
ಛ » 10͘Β͍લʹΈͨײ͡Λ࠶ݱʂ » ݱͷFW͔ΒΈΕҟ༷ʹγϯϓϧʂ » 1ϑΝΠϧɺؔ10ݸ͘Β͍ͰͰ͖ͯΔͧʂ » ॳ৺ऀʹΉ͔͍ͣ͠OOPແ͠ʂؔͰ͓̺ʂ
<?php // index.php require_once(dirname(dirname(__FILE__)) . "/app/ore.php"); define("DB_DSN", 'sqlite:' . dirname(dirname(__FILE__))
. "/db.sqlite"); option('HTML_TITLE', "ͳ͔ͭ͠ͷੈքͰ͢"); route('/', 'post_list'); route('/post/create', 'post_create'); route('/post/:id', 'post_show'); route('/reset', 'post_reset'); run(); ?>
None
route('/', 'post_list'); route('/post/create', 'post_create'); route('/post/:id', 'post_show'); route('/reset', 'post_reset'); run();
function route($path = null, $func_name = null) { // ؔऴྃ࣌ʹফ͑ͳ͍ྻͱͯ͠$route_listΛએݴ
static $route_list = array(); // $keyͱ$val྆ํʹԿ͔ೖ͍ͬͯΕɺ$pathΛΩʔʹ$func_nameΛอଘ if (!is_null($path) && !is_null($func_name)) $route_list[$path] = $func_name; // Ҿࢦఆແ͠ͳΒɺ$route_listΛ·Δ͝ͱฦ͢ if (is_null($path)) return $route_list; // $pathҾ͕༗ΓɺͦͷΩʔ͕route_listʹ͋ΕɺͦΕΛฦ͢ if (isset($route_list[$path])) return $route_list[$path]; // Έ͔ͭΒͳ͔ͬͨͷͰɺnullΛฦ͢ return null; }
function run() { // ݱࡏͷΞΫηεʹରԠ͢ΔPathΛݕࡧ $path = find_match_path(); // pathʹରԠ͢Δ໊ؔΛͱΓͩ͠ɺ࣮ߦ
call_user_func(route($path)); }
function find_match_path() { $uri = $_SERVER['REQUEST_URI']; foreach (path_regex() as $path
=> $regex) { if (preg_match($regex, $uri, $matches)) { $match_path = $path; break; } } if (!isset($match_path)) { return 'notfound'; } foreach ($matches as $k => $v) { if (preg_match('/^[0-9]/u', $k)) { continue; } option($k, urldecode($v)); } return $match_path; }
function path_regex() { $regex_list = array(); foreach (route() as $route
=> $cb) { $regex_list[$route] = '#\A' . preg_replace_callback( '#:([\w]+)#', function ($m) { return "(?P<{$m[1]}>[^/]+)"; }, $route ) . '\z#'; // ex: #\A/post/(?P<id>[^/]+)\z# } return $regex_list; }
function render($template, $params = array()) { extract($params); ob_start(); include(TEMPLATE_DIR .
$template); $html = ob_get_clean(); echo $html; }
// ݺͼग़͠ render('ʙʙ',array('name'=>$name)); ↓ // include͞ΕΔςϯϓϨͷίʔυ <?php echo $params['name']; ?>
// ↑Ͱͳ͘ɺ↓Έ͍ͨʹ͔͖͍ͨΑͶʁ <?php echo $name; ?>
͘ͳΔͷͰ͜ͷΜͰ » Githubʹʢ͔ͣ͠ͳ͕Βʣ͕͍͋ͬͯ·͢ͷͰɺ ޙͰಡΜͰস͍ͬͯͩ͘͞ɻ
ʮͨͷ͍͠ʂʯ » ͳ͔ͭ͠ςΫχοΫΛͻ͞ͼ͞ʹ͔ͭ͏ͱ৽ʂ » ͳΜ͔ͩΜͩମ͕͓΅͑ͯͯεΠεΠ͔͚ͯͨͷ͠ ͍ʂ » Ͳ͏Ͱ͢ʁ10લͷςΫχοΫझ͕͋Γ·͢Α Ͷʁ »
ʮΦϨΦϨFW࡞Γͬͯͨͷ͍ͦ͠͏ʙʂʯ » Ͳ͏Ͱ͢ʁͨͷͦ͠͏Ͱ͠ΐ͏ʁ
Έͳ͞Μͷײ ʮੲ͡Όͳ͍͔ʂ;͚͟Μͳʂʯ
͜ͷ··ͩͱՈʹؼΕͳ͘ͳ Γͦ͏ͳͷͰ » ͏ҰͭϑϨʔϜϫʔΫΛ࡞Γ·ͨ͠
Ore2 Framework രʂ » ΦϨΦϨϑϨʔϜϫʔΫʂ » ࡞̏ഒͷࡾʂ » https://github.com/uzulla/Ore2
ಛ » OreͱҧͬͯOOPରԠʢʁʣʂ » PSR-3,4,7,11(Draft)ʹ(ଟ)४ڌʂ » ྲྀߦΔ͔͠Εͳ͍PSR-7ΛͬͨϛυϧΣΞʹ ରԠʂ » PHP7ରԠʂͱ͍͏͔7Ҏ߱Ͱ͔͠͏͔͝ͳ͍ʂ
ػೳ () » ϧʔλʔ » TwigͬΆ͍ςϯϓϨʔτΤϯδϯ » ϩΨʔ » PSR-7ɺMiddlewareରԠ
» ίϯςφʢϩέʔλʣ » ηογϣϯ
ػೳ (ݱ࣮) » ϧʔλʔ » TwigͬΆ͍ςϯϓϨʔτΤϯδϯ × » ϩΨʔ »
PSR-7ɺMiddlewareରԠ˚ » ίϯςφʢϩέʔλʣ » ηογϣϯ ˚
ʮࡾͰແཧ!!ʯ » ςϯϓϨʔτΤϯδϯ » ύʔαʔϨΩαʔτʔΫφΠβʔ » Request/ResponseInterface ʢͱਵ͢ΔServerRequestInterfaceʣ࣮େม » ZendઌੜʹཔΓ·ͨ͠
» ηογϣϯ » ੜࣽ͑ʢਅͷPSR-7ରԠͷηογϣϯ໘ʂʣ
<?php //index.php declare(strict_types=1); include __DIR__."/../vendor/autoload.php"; // Route ొ $router =
new \Ore2\Router(); $router->get('/', function(){ return $this->html('<span style="color:red">123</span>'); }); $router->get('/name/:name', function(){ return $this->html("hello {$this->c->routeParams['name']}"); }); $router->get('/sample', '\\MyApp\\SampleAction::sample'); $router->get('/sample_json', '\\MyApp\\SampleAction::sampleJson'); // PSR-7ΦϒδΣΫτͷϑΝΫτϦΛ࣮͢ΔͷఘΊ·ͨ͠ $request = \Zend\Diactoros\ServerRequestFactory::fromGlobals(); $response = new \Zend\Diactoros\Response(); // route ղܾ $match_result = $router->findMatch($request->getMethod(), $request->getRequestTarget()); // ֤छϔϧύʔΛίϯςφʹ͍ΕΔ $container = new \Ore2\Container(); $container->config = require __DIR__."/../settings.php"; $container->session = new \Ore2\Session(new \Ore2\Session\Storage\PHPSession()); $container->template = new \Ore2\Template($container->config['template']); $container->logger = new \Ore2\Logger(); // ΞΫγϣϯΛ࡞ $action = $match_result->buildAction($container); // Middlewareͱ࣮ͯ͠ߦ $seqencer = new \Ore2\MiddlewareSequencer([ new \Ore2\Transmitter(), $action ]); $seqencer($request, $response);
None
Ͱίʔυհ… » ͱ͍͕ͨ͠ɺ͕͢͞ʹεϥΠυͰͭΒͭΒհ͢Δ ͷ͕ݫ͍͠ίʔυྔ » ͳͷͰμΠδΣετͰհ » ڵຯ͕͋ΔํGithubͰݟ͍ͯͩ͘͞
» PHP7લఏͰΈ࢝Ίͨ͠ɺ͔ͤͬ͘ͳͷͰ declare(strict_types=1);ɺҾܕࢦఆฦܕ ࢦఆυϯυϯ༩ » PSR-4ରԠͳͷͰComposerͷAutoloader » ϧʔλʔ໊ؔͰͳ͘Ϋϩʔδϟɺ·ͨΫϥεϝ ιου໊ࢦఆ͕Մೳ »
ྲྀੴʹHTTPϝιουʹରԠ » LoggerPSR-3४ڌ
» ίϯςφҙຯͳ͘PSR-11(Draft)ʹରԠ͠ɺ ArrayAccessͱ__get/set࣮ » Session(ҰԠ)PSR-7Ͱಈ͘Α͏ʹ࡞ » CSRFΨʔυྫ֎τϥοϓΛPSR-7 Middleware ͱ࣮ͯ͠ »
relay(relayphp.com)෩ͷϛυϧΣΞ࣮ߦػೳΛ ༻ҙ » ϧʔτઃఆͰɺΞΫγϣϯʹΫϩʔδϟΛͯ͠ bindToͰ$thisܦ༝Ͱ৭ʑ৮ΕΔ » etc,etc
PSRͰॻ͚ͦ͏ͳͷશ෦ॻ ͍ͯΈͨ » ͱ͍͏͜ͱͰɺݸਓతʹຬͰ͢ʂ » ʢԿΛ͍ͬͱΔΜ͍ͩͭ͜ʣ
PSR-7ʹ͍ͭͯͪΐͬͱհLT
PSR-7ʹ͍ͭͯ » Request/Response ObjectͷInterface༷ » ϒϥβ͔ΒͷϦΫΤετใ͕શ෦͍ͬͨΦϒδ ΣΫτ » PerlͰPSGIɺRubyͩͱRackΈ͍ͨͳͷ »
PHPͰաڈͳ͔ͬͨΘ͚Ͱͳ͍͕ɺFWຖʹޓ ੑͳ͔ͬͨ
ͳʹ͕خ͍͠ͷʁ » ී௨ɺಛʹ͏Ε͘͠ͳ͍ » ݸਓతʹ » ΦϨΦϨFWѪՈతʹָʹςετͰ͖ͦ͏ » ଞͷݴޠͬΆͯࣗ͘વʹײͯ͡خ͍͠ »
ReactPHPΞϓϦέʔγϣϯαʔόʔ͕ରԠ͢ Εָͦ͠͏ʂ=>࣮ࡍπΠʔτΛݟͨ » Middleware͕ͨͷͦ͠͏
ͳʹ͕خ͘͠ͳ͍ͷʁ » ʢ໘ʣແବ͕૿͑ΔͷͰ͘ͳΔ » $_*ΛͰ৮Δࠓ·Ͱͱޓੑ͕ແ͍ » PHP७ਖ਼ͷsession͕(ຊདྷͳΒ)ແ͘ͳΔ » ·ͩ͑Δ࣮͕બͳ͍
·͋ɺී௨ͷਓؾʹ͠ͳ͍ » FWͷϔϧύγϣʔτΧοτͰӅṭ͞ΕΔͩΖ͏ » FW੍࡞ऀ͚͕ͩؾʹ͍ͯ͠Ε͍͍ͷͰ… » ͦ͏ɺΦϨΦϨFW੍࡞ऀͳΒؾʹ͠ͳ͍ͱͶʂʈʈ
// ZendͷPSR-7࣮ $request = \Zend\Diactoros\ServerRequestFactory::fromGlobals(); $response = new \Zend\Diactoros\Response(); //
ΞΫγϣϯΛϧʔλʔͰܾఆ ΞΫγϣϯ = ϧʔλʔ($request); // ࣮ߦ $response = ΞΫγϣϯ($request, $response); // ԿΒ͔ͷํ๏Ͱ$responseΛૹ৴ ૹ৴͢Δ܅($response);
// request͔ΒPOSTऔಘྫ $name = $request->parsedBody['name'] ?? ''; // ϨεϙϯεΦϒδΣΫτ࡞ $response
= $response ->withStatus(200); ->withHeader('Content-Type', 'text/html'); $body = new \Zend\Diactoros\Stream('php://memory', 'w'); $body->write("Hello world"); $response = $response->withBody($body); return $response; // ͜ͷޙͰૹ৴܅ͳͲͰૹ৴͞ΕΔ
PSR-7 middlewareʹ͍ͭͯ » ঢ়ଶ͕άϩʔόϧม͔ΒҾ͖͕͞ΕͨͷͰɺϑΟ ϧλʔΈ͍ͨͳ͜ͱ͕Γ͍͢ » Rack MiddlewarePlack Middleware »
ʮͦ͜ΒͷFWʹϛυϧΣΞ͋Δ͡ΌΜʁʯ ʮͦΕ͕શ෦ͷFWͰڞ௨ͷIFʹͳΕɺເ͕ʁʯ ʮʮ͕Δʂʂʯʯ
ϛυϧΣΞͷ֓೦ਤ (A,B,C,DϛυϧΣΞ) A B C D |-req&res->| |-req&res->| |-req&res->| |
|<-res-----| |<-res-----| |<-res-----|
༻్ແɺΦϨΦϨతʹ ເ͕͋Δ » ೖྗ/ग़ྗͷՃ » CSRFରࡦ » ೝূ » ҆શੑ্ʹ༗༻ͳϔομʔͷૹ৴
» ग़ྗ࣌ʹஔ
» ϑοΫ » Ωϟογϡ » ϩΨʔ » ྫ֎Ωϟον
PSR-7ͷ͠ΜͲ͍ͱײͨ͡ॴ » ͋͘·ͰHTTPϦΫΤετͷঢ়ଶͳͷͰ… » ͍͕ͬͯͨɺ$_SESSION͕ͳ͍ʂ » Ore2ͰޡຐԽ࣮ͯ͠ » ͦͦimmutableͳPSR-7ͱ૬ੑ͕ѱ͍ »
͏͏ʔʔΜ…
·͋Ͱָ͍͠ʂ » mod_phpͱ͔php-fpmͱ͔͖ͨͥʂ » ͱ͍͏ํੋඇͬͯΈ͍͔͕ͯͰ͠ΐ͏͔
!!!
Ͱͳ͍
ʮΦϨΦϨϑϨʔϜϫʔΫͷͩͬͨ͠ͷͰʁʯ » ͜͜·Ͱͯ͢༨ஊʂ » ͜ͷΑ͏ʹɺੜࣽ͑ͷٕज़ΛάΠάΠͬͯࢼ͢ͷ ɺΦϨΦϨͷָ͠͞ͳͷͰ͢ʂʂ » Ͳ͏Ͱ͔͢ʁͨͷͦ͠͏Ͱ͠ΐ͏ʁ
ͯ͞ɺOreͱOre2ΛৼΓฦͬ ͯΈ·͠ΐ͏ » Oreͱʹ͔͘࠷খݶͰ͔͔Ε͍ͯΔ » Ore2ڽ͍ͬͯͳ͍͚Ͳཉுͬͨ » Ͱɺ࣮ࡍ͜ΕͲΕ͘Β͍େมͳͷʁ
None
» Ore » 9 commits / 588 ++ / 168
-- » Ore2 » 62 commits / 4,106 ++ / 1,063 --
ͱɺΈΔͱɺͲ͏Ͱ͔͢ » ʮॴḨ͜ΜͳͷʢʣͳͷʹɺͦΕͬΆ͘͢Δͷ໘ ͦ͏…ʯ » ͦ͏͓͍·ͤΜ͔ʁ » ʮΘͨ͠ʹͰ࡞ΕΔ͔ͳʁʯ » ͦ͏ࢥ͏͔͠Ε·ͤΜ…
ͦΜͳ͜ͱͳ͍ʂ ͋ͳͨࠓதʹ ͋ͳ͚ͨͩͷ FWʂʂ
ࡢࠓͷPHP… » ϥΠϒϥϦ͕ΊͬͪΌͦΖͬͯΔʂ
» ʮϧʔλʔʁʯ » ࢁ͋Γ·͢ʂ » ʮςϯϓϨʔτΤϯδϯʁʯ » ࢁ͋Γ·͢ʂ » ʮ˓˓ʁʯ
− ʢଟʣࢁ͋Γ·͢ʂ
େ(OSS)ͷܙΈʹײँ…ʂ » ΠέͯΔϥΠϒϥϦΛެ։ͯ͠Βͬ͠ΌΔํʑ » ຊԿਓ͍Βͬ͠Ό͍ͬͯΔ
બͿͷ͠ΜͲ͍ͷͰ » ·͋ΦϨΦϨ͔ͩΒαϯϓϧͷงғؾ͔Βؾܰʹ͑Β ΅͏ʂ
ͱ͍͏͜ͱͰͬͯΈͨ » ຊࡾͭ! » Oredakedenai FW! » ςϯϓϨʔτΤϯδϯTwig » ϧʔλʔzonuexe/simple-routing
<?php include __DIR__."/../vendor/autoload.php"; \MyApp\Db::$pdo = new \PDO("sqlite:".__DIR__."/../db.sqlite"); $container = [
'template' => new Twig_Environment( new Twig_Loader_Filesystem(__DIR__."/../template") ) ]; $routing_map = [ ['GET', '/', '\MyApp\Post::showList' ], ['GET', '/post/:id', '\MyApp\Post::show', ['id' => '/^(\d+)$/']], ['POST', '/post/create', '\MyApp\Post::create' ], ['GET', '/reset', '\MyApp\Post::reset' ], '#404' => '\MyApp\Post::notfound' ]; $router = new \Teto\Routing\Router($routing_map); $action = $router->match($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); if (!preg_match('|\A([\\a-zA-Z0-9_]*)::([a-zA-Z0-9_]+)\z|u', $action->value, $matches)) throw new \InvalidArgumentException('invalid action string:' . $action->value); $method_name = $matches[2]; (new $matches[1]($container))->$method_name($action->param);
» 2 commits / 398 ++ / 0 -- »
࡞࣌ؒ30͆ʂ » ͍ʂ
» ެ։͞Ε͍ͯΔϥΠϒϥϦΛ͔ͭͬͯFWΛͭ͘Δͷ खܰʂʂʂ
͡Ό͋ͳΜͰࠓճૉखͰೋͭ ॻ͍ͨͷʁ » झຯͰ͢
ͪΐͬͱ·ͬͯɺͦΕͰΦϨΦϨͱ͍͑Δͷ͔ʁ » ॻ͍ͨॴ5ʙ10ߦ͘Β͍ͳͷʹΦϨΦϨʁ » ͪΖΜ͜Εوํ͚ͩͷΦϨΦϨͱ͍͑·͢ » ʢ·͋ɺOre2ͩͬͯTwig͔ͭͬͯΔ͠…ʣ » ͍·֎෦ͷϥΠϒϥϦ͔ͭ͏ͷ͕વͰ͋Δ »
͋ΜͳFW͜ΜͳFWͩͬͯɺͳΜ͔ͩΜͩ Symfony͋ͨΓͷίϯϙʔωϯτΛ͔͍ͭͬͯΔ
͜ΕͰखܰʹΦϨΦϨͰ͖Δʂ » ͕ࣗॻ͚ͳ͍ͱ͜ΖؾܰʹआΓΔ » Githubͷ͓ӄͰʮਓؾʯελʔͰՄࢹԽ » ʢਓؾ≠ग़དྷʣ » ΦϨΦϨϑϨʔϜϫʔΫ࡞ʹ࠷ߴͷ࣌Ͱʁ »
Ͱ͖Δͱ͜Ζ͔ΒؾܰʹΦϨΦϨʂ
» ͱ͍͏͜ͱͰɺΒͳ͍ཧ༝͕͋Γ·ͤΜͶʂ(ʁ)
·ͱΊʹೖ͍͖ͬͯ·͢ » ʢ࣌ؒௐͱ͍͍·͢ʣ
ϛογϯάϐʔεʹؾ͚Δ » ϗϯτʹ0͔Β͔͚Δʁҙ֎ͱ͔͚ͳ͍ » ຊʹ0͔Βͭͬͯ͘Έͳ͍ͱɺΘ͔Βͳ͍ͷ͕Θ ͔Βͳ͍ » ՌͦͷͷΑΓɺաఔͰ৭ʑͳ͕ಘΒΕΔ » ͔ͭ͏͚ͩɺಡΉ͚ͩͰͳ͍
» ීஈ͏͚ͩͷϥΠϒϥϦͷҙຯͱԞਂ͞ΛΕΔ » PHP͚ͩͰͳ͍͕ࣝඞཁʹͳ͖ͬͯͨΓ
ྗ্͕Δ » ίʔυಡղྗ্͕Δ » ίʔυΛత࣋ͬͯಡΉͷޮՌత » యܕతͳελΠϧΛ͓΅͑ΒΕΔ » ෳͷFWͰ͔ͭΘΕ͍ͯͨΒఆ൪ͬΆ͍ »
ઃܭྗ্͕Δ
Λແࢹ͠ɺγϯϓϧॻ͖͢ͱ » ʢࣗͰॻ͚ΔϨϕϧʹམͱ͠ࠐΉͱʣ » ٯʹطଘFWͷ͕ݟ͑Δ » ෳࡶͳͷಛผͳέʔεʹରԠ͢ΔҝͩͬͨΓ » ʮ͍ʯʮॏ͍ʯͷʹཧ༝͕͋ͬͨΓ »
ʮ͍ʯϥΠϒϥϦ͕৭ʑ͍ͯ͠Δͷʹؾ͘
ݹ͍ٕज़ॏཁͱվΊͯؾ͘ » ࠓ෩ͳFWͰɺ࣮વͲΖ͔ͬͨ͘͞Γ » ྫɿ݁ہͳΜͰͰ͖Δਖ਼نදݱਖ਼ٛʂ » ʢࠓճϧʔλʔͷਖ਼نදݱ͍ճ͠ʣ » ͳΜ͔ͩΜͩྺ࢙͋Δٕज़͑͘Δٕज़ͩͱؾ ͘
» ʮ͕ΜͬͯΉ͔ͭͦ͠͏ͳࣄΛษڧ͍ͯͧ͘͠ʂʯ ʮύʔαϨΩαʔτʔΫφΠβʔεςʔτϚγϯʯ ʮοοʯ
ͱֶ͍ͬͨͼ͕͋Δ » PHPΧϯϑΝϨϯεʹ͍Βͬ͠ΌΔ΄Ͳɺͳʹֶ͔ Ϳͷ͕͖ͳਓͳΒ͖ͬͱͨͷ͍͠ » ͳΜ͔ͩΜͩͰΈΜͳͬͯΔͬͯɺͨͷ͍ͬͯ͠ʂ » ͱ͍͏͜ͱͰ » ΦϨΦϨ͠Α͏ͥʂ
ΦϨΦϨ্ڃऀϓϨΠ » ͏ΦϨΦϨʹ͖ͨ(Γͨ)ํ » റΓϓϨΠʢมΛҰݸΘͳ͍ͱ͔ʣ » ৽͍༷͠Λ࣮ϓϨΠʢࠓճOre2͕PSR7ʣ » ͋ΔFWͷίϐʔϓϨΠʢࠓճOre͕͔ͳΓLimonde ͷϚωʣ
» ੍ݶ࣌ؒͰͲ͜·Ͱͭ͘ΕΔ͔ʢػೳΛఘΊΒΕΔ ͔ʣϋοΧιϯϓϨΠ ϫΠϫΠΔͷͨͷ͍͠Ͱ͢Αʂʂ
ͦ͏͍͑ɺΦϨΦϨͨ͠ޙ ʹͳʹΛ͢Ε͍͍ͷ͔ʁ » τʔΫͷԠืͷ࠷ޙʹॻ͍ͯ·͕ͨ͠…
ࣺͯΑ͏ʂʂʂ
ΦϨΦϨΛ͏ͷඍົ » ʮ͍͍ͨΦϨΦϨFW͑ͳ͍ɺ ͜Μͳੈͷத͡Όʢʣʯ » ΦϨΦϨઑΓ͕ͪ » ΦϨΦϨଞਓʹཧղ͞ΕͮΒ͍ » ͕ͱͳ͏ͱɺΦϨΦϨͷࣗ༝ָ͕ͭ͞͠͞Β
͞ʹͳΔ » ͍͔ͭϝδϟʔʁͰࠓͰͳ͍ͦͬͱด͡Α͏
ͭ·Γ » ਓੜҰҎ্ΦϨΦϨͯ͠ » ͙͢ʹࣺ͍ͯͯ͜͏ͥʂ » લ͚ͩΛ͍ͯʂ » ΤϯδϣΠʂΦϨΦϨʂ
ΦϨΦϨτʔΫҎ্Ͱ͢ʂ օ͞·ͷ͝ਗ਼ௌ ΦϨ͍ਃ্͛͠·͢ʂ