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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
uzulla
April 16, 2016
Programming
21k
15
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPer人生、一度はフレームワークを作っておこう!
PHPカンファレンス北海道 2016 発表資料
20160416
uzulla
April 16, 2016
More Decks by uzulla
See All by uzulla
ALL CODE BASE ARE BELONG TO STUDY
uzulla
30
7.7k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
580
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
2.3k
似たもの同士のPerlとPHP
uzulla
1
300
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
230
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
330
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
240
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
3.2k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.5k
Other Decks in Programming
See All in Programming
ふつうのFeature Flag実践入門
irof
8
4.2k
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
300
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
410
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
180
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.5k
Webフレームワークの ベンチマークについて
yusukebe
0
180
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
630
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
13
6.3k
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
Oxlintのカスタムルールの現況
syumai
6
1.2k
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Chasing Engaging Ingredients in Design
codingconduct
0
230
Odyssey Design
rkendrick25
PRO
2
710
New Earth Scene 8
popppiees
3
2.4k
Design in an AI World
tapps
1
250
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
310
Claude Code のすすめ
schroneko
67
230k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
400
Optimizing for Happiness
mojombo
378
71k
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͑ͳ͍ɺ ͜Μͳੈͷத͡Όʢʣʯ » ΦϨΦϨઑΓ͕ͪ » ΦϨΦϨଞਓʹཧղ͞ΕͮΒ͍ » ͕ͱͳ͏ͱɺΦϨΦϨͷࣗ༝ָ͕ͭ͞͠͞Β
͞ʹͳΔ » ͍͔ͭϝδϟʔʁͰࠓͰͳ͍ͦͬͱด͡Α͏
ͭ·Γ » ਓੜҰҎ্ΦϨΦϨͯ͠ » ͙͢ʹࣺ͍ͯͯ͜͏ͥʂ » લ͚ͩΛ͍ͯʂ » ΤϯδϣΠʂΦϨΦϨʂ
ΦϨΦϨτʔΫҎ্Ͱ͢ʂ օ͞·ͷ͝ਗ਼ௌ ΦϨ͍ਃ্͛͠·͢ʂ