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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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.5k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
510
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
2k
似たもの同士のPerlとPHP
uzulla
1
280
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
210
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
310
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
220
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
3k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.4k
Other Decks in Programming
See All in Programming
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
400
今こそ知るべき耐量子計算機暗号(PQC)入門 / PQC: What You Need to Know Now
mackey0225
3
370
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
170
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
600
組織で育むオブザーバビリティ
ryota_hnk
0
170
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
2.4k
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
680
AIで開発はどれくらい加速したのか?AIエージェントによるコード生成を、現場の評価と研究開発の評価の両面からdeep diveしてみる
daisuketakeda
1
960
SourceGeneratorのススメ
htkym
0
190
AI時代の認知負荷との向き合い方
optfit
0
130
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
180
AI 駆動開発ライフサイクル(AI-DLC):ソフトウェアエンジニアリングの再構築 / AI-DLC Introduction
kanamasa
12
6.4k
Featured
See All Featured
Tell your own story through comics
letsgokoyo
1
800
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.2k
Fireside Chat
paigeccino
41
3.8k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
170
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8.6k
Building an army of robots
kneath
306
46k
Optimizing for Happiness
mojombo
379
71k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
450
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
What's in a price? How to price your products and services
michaelherold
247
13k
The untapped power of vector embeddings
frankvandijk
1
1.6k
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͑ͳ͍ɺ ͜Μͳੈͷத͡Όʢʣʯ » ΦϨΦϨઑΓ͕ͪ » ΦϨΦϨଞਓʹཧղ͞ΕͮΒ͍ » ͕ͱͳ͏ͱɺΦϨΦϨͷࣗ༝ָ͕ͭ͞͠͞Β
͞ʹͳΔ » ͍͔ͭϝδϟʔʁͰࠓͰͳ͍ͦͬͱด͡Α͏
ͭ·Γ » ਓੜҰҎ্ΦϨΦϨͯ͠ » ͙͢ʹࣺ͍ͯͯ͜͏ͥʂ » લ͚ͩΛ͍ͯʂ » ΤϯδϣΠʂΦϨΦϨʂ
ΦϨΦϨτʔΫҎ্Ͱ͢ʂ օ͞·ͷ͝ਗ਼ௌ ΦϨ͍ਃ্͛͠·͢ʂ