Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Going Bare - Writing The Web Without A Framework - Longhorn PHP 2019

Going Bare - Writing The Web Without A Framework - Longhorn PHP 2019

This talk was given at Longhorn PHP 2019.

If you’ve only ever experienced web development through a web framework, you’re missing out. Have you ever been tempted to rewrite a codebase in your favorite framework? That’s a smell that you need to come to this talk.

Being comfortable developing without a framework is a crucial skill to have for refactoring legacy applications. In this talk I show you how to harness the power of going “frameworkless” so you’ll feel empowered to make better decisions in your next web project. Be set free from your web-framework ball and chain.

Sammy Kaye Powers

May 03, 2019

More Decks by Sammy Kaye Powers

Other Decks in Programming


  1. Going Bare Writing the web without a framework Sammy Kaye

    Powers 2019-05-03
  2. joind.in/talk/4b6f9 @SammyK #LonghornPHP Slides Get the joind.in/talk/4b6f9

  3. joind.in/talk/4b6f9 @SammyK #LonghornPHP frameworks The point is not <3 frameworks!

  4. joind.in/talk/4b6f9 @SammyK #LonghornPHP opinion It’s OK to have an

  5. joind.in/talk/4b6f9 @SammyK #LonghornPHP experiment It’s OK to

  6. joind.in/talk/4b6f9 @SammyK #LonghornPHP Bootstrapping / ˈbo ͞ otˌstraˌpiNG / Define:

    (…at least for this talk) Code that acts as an entry point into an app.
  7. joind.in/talk/4b6f9 @SammyK #LonghornPHP Boilerplate / ˈboilərˌplāt / Define: The “glue”

    code that ties components together. (…at least for this talk)
  8. joind.in/talk/4b6f9 @SammyK #LonghornPHP Frameworks are a tool

  9. joind.in/talk/4b6f9 @SammyK #LonghornPHP Going bare is a skill (that you

    don’t get with a framework)
  10. joind.in/talk/4b6f9 @SammyK #LonghornPHP The of going bare skill • Writing

    bootstrap & boilerplate • Choosing exact components • Use different paradigms • Use those skills on domain code (Get to know the component ecosystem) (Like singleton, et al) (Gives you more control over how components interact) (Makes you better at writing your domain code)
  11. joind.in/talk/4b6f9 @SammyK #LonghornPHP Myths about going frameworkless

  12. joind.in/talk/4b6f9 @SammyK #LonghornPHP Myth #1 You must write everything from

  13. joind.in/talk/4b6f9 @SammyK #LonghornPHP Myth #2 You’re inherently anti-framework or anti-convention

  14. joind.in/talk/4b6f9 @SammyK #LonghornPHP Myth #3 You’ll spend most of your

    time on boilerplate instead of on domain code
  15. joind.in/talk/4b6f9 @SammyK #LonghornPHP Myth #4 You must be an architecture

  16. joind.in/talk/4b6f9 @SammyK #LonghornPHP Myth #5 You like pain

  17. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros Framework Cons

  18. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros

  19. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros

  20. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros crazy fast You get started

  21. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros First-time install time minutes! 5

  22. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros

  23. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros boilerplate all the things You don’t

    have to Con but it can be a
  24. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros bootstrap & boilerplate code You don’t

    have to maintain
  25. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros battle-tested The code is

  26. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros conventions Ready-to-follow Con but it can

    be a
  27. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros documentation Most frameworks have great

  28. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros marketable It makes you more

  29. joind.in/talk/4b6f9 @SammyK #LonghornPHP Pros pragmatic They are often

  30. joind.in/talk/4b6f9 @SammyK #LonghornPHP cons? What about the

  31. joind.in/talk/4b6f9 @SammyK #LonghornPHP Cons legacy codebases Useless for

  32. joind.in/talk/4b6f9 @SammyK #LonghornPHP Cons cruft They fill your project with

  33. joind.in/talk/4b6f9 @SammyK #LonghornPHP Cons Cruft • Deployment takes longer •

    Upgrading pulls in all the new features
  34. joind.in/talk/4b6f9 @SammyK #LonghornPHP Cons tightly couple Easier to due to

  35. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  36. 5.3

  37. 5.7 2018-09-04

  38. None
  39. 5.7 Did not support laravelcollective/html mccool/laravel-auto-presenter

  40. None
  41. None
  42. joind.in/talk/4b6f9 @SammyK #LonghornPHP Cons upgrading Framework-specific deps can keep you

  43. joind.in/talk/4b6f9 @SammyK #LonghornPHP The The Cons Pros seem great are

  44. joind.in/talk/4b6f9 @SammyK #LonghornPHP Why would you go bare? (To answer

    we must ask…)
  45. joind.in/talk/4b6f9 @SammyK #LonghornPHP When should you go bare?

  46. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  47. joind.in/talk/4b6f9 @SammyK #LonghornPHP Greenfield Legacy Depends

  48. joind.in/talk/4b6f9 @SammyK #LonghornPHP 1% 99% 90% 10% Go Bare Framwork

    Greenfield Legacy Going bare vs framework
  49. joind.in/talk/4b6f9 @SammyK #LonghornPHP How do you go bare?

  50. joind.in/talk/4b6f9 @SammyK #LonghornPHP from scratch You could just write

  51. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  52. joind.in/talk/4b6f9 @SammyK #LonghornPHP That means writing all the things Router

    DBAL/ORM Dep Injection Logger
  53. joind.in/talk/4b6f9 @SammyK #LonghornPHP reinventing the wheel But that’s like

  54. joind.in/talk/4b6f9 @SammyK #LonghornPHP Better Way™ There’s a

  55. joind.in/talk/4b6f9 @SammyK #LonghornPHP po- nents Com-

  56. joind.in/talk/4b6f9 @SammyK #LonghornPHP components has a healthy ecosystem of

  57. joind.in/talk/4b6f9 @SammyK #LonghornPHP using them You’re probably already

  58. joind.in/talk/4b6f9 @SammyK #LonghornPHP built on them Most frameworks are zend-router

    zend-db zend-di zend-log
  59. joind.in/talk/4b6f9 @SammyK #LonghornPHP choose ur candy Going bare lets you

    Look at all those smarties! Yum!
  60. joind.in/talk/4b6f9 @SammyK #LonghornPHP I like smarties

  61. joind.in/talk/4b6f9 @SammyK #LonghornPHP Router DBAL/ORM Dep Injection Logger

  62. joind.in/talk/4b6f9 @SammyK #LonghornPHP zend-router fast-route php-router phroute Routers Tons of

  63. joind.in/talk/4b6f9 @SammyK #LonghornPHP Easily installed with

  64. joind.in/talk/4b6f9 @SammyK #LonghornPHP bag o’ candy A framework is like

    a Comes with licorice? Yuck!
  65. joind.in/talk/4b6f9 @SammyK #LonghornPHP I don’t like licorice

  66. joind.in/talk/4b6f9 @SammyK #LonghornPHP components When you go bare don’t just

    magically start working together
  67. joind.in/talk/4b6f9 @SammyK #LonghornPHP Key: Get comfy with bootstrapping & boilerplate

    code It’s really not that bad
  68. joind.in/talk/4b6f9 @SammyK #LonghornPHP examples Real-world

  69. joind.in/talk/4b6f9 @SammyK #LonghornPHP conventions When going bare, there aren’t any

    …so this is a way, not the way
  70. joind.in/talk/4b6f9 @SammyK #LonghornPHP Greenfield Let’s start with

  71. joind.in/talk/4b6f9 @SammyK #LonghornPHP Case study Raw CSV Calculate
 & save

    to DB Show report Client’s server Our server
  72. joind.in/talk/4b6f9 @SammyK #LonghornPHP Case study Download CSV & calculate CLI

    View the report HTTP Endpoint
  73. joind.in/talk/4b6f9 @SammyK #LonghornPHP coding domain in 5 mins Install framework

  74. joind.in/talk/4b6f9 @SammyK #LonghornPHP 61components installed before we code https://framework.zend.com/downloads

  75. joind.in/talk/4b6f9 @SammyK #LonghornPHP go micro We could… Slim Silex (et

  76. joind.in/talk/4b6f9 @SammyK #LonghornPHP Silex DEAD!

  77. joind.in/talk/4b6f9 @SammyK #LonghornPHP go bare! :) But let’s

  78. joind.in/talk/4b6f9 @SammyK #LonghornPHP Start in the CLI (Just like when

    you use a framework!)
  79. joind.in/talk/4b6f9 @SammyK #LonghornPHP 1. Make an empty composer.json or… $

    composer init
  80. joind.in/talk/4b6f9 @SammyK #LonghornPHP 2. Make a folder for domain code

    $ mkdir src
  81. joind.in/talk/4b6f9 @SammyK #LonghornPHP 3. Add autoloading $ composer \ dumpautoload

    And then run…
  82. joind.in/talk/4b6f9 @SammyK #LonghornPHP Now just install your components & tie

    them together
  83. joind.in/talk/4b6f9 @SammyK #LonghornPHP Key: Get comfy with bootstrapping & boilerplate

    code It’s really not that bad
  84. joind.in/talk/4b6f9 @SammyK #LonghornPHP Case study Download CSV & calculate CLI

    View the report HTTP Endpoint
  85. joind.in/talk/4b6f9 @SammyK #LonghornPHP Install a console component $ composer require

    symfony/console (or maybe you like zendframework/zend-console)
  86. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Console/Runner.php

  87. joind.in/talk/4b6f9 @SammyK #LonghornPHP We get to make our first bootstrap

  88. joind.in/talk/4b6f9 @SammyK #LonghornPHP run (sans .php extension) $ chmod +x

  89. joind.in/talk/4b6f9 @SammyK #LonghornPHP $ ./run

  90. joind.in/talk/4b6f9 @SammyK #LonghornPHP B.A.U. Now it’s just src/Console/Runner.php

  91. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Console/CalculateReportsCommand.php

  92. joind.in/talk/4b6f9 @SammyK #LonghornPHP $ ./run

  93. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  94. joind.in/talk/4b6f9 @SammyK #LonghornPHP Congrats!

  95. joind.in/talk/4b6f9 @SammyK #LonghornPHP Install the DI container $ composer require

    pimple/pimple (Choose your poison)
  96. joind.in/talk/4b6f9 @SammyK #LonghornPHP Need to make singleton ready src/Application.php

  97. joind.in/talk/4b6f9 @SammyK #LonghornPHP Singleton Isn’t that an anti-pattern?

  98. joind.in/talk/4b6f9 @SammyK #LonghornPHP https://en.wikipedia.org/wiki/Singleton_pattern

  99. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  100. joind.in/talk/4b6f9 @SammyK #LonghornPHP Singleton •Ensures one & only one instance

    •Global access (static function) •Initialization on first access
  101. joind.in/talk/4b6f9 @SammyK #LonghornPHP Fatal error: Call to private App\Application::__construct() src/Application.php

  102. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Application.php Global access + instantiate on first

  103. joind.in/talk/4b6f9 @SammyK #LonghornPHP Get an instance of Application

  104. joind.in/talk/4b6f9 @SammyK #LonghornPHP Prevent cloning src/Application.php

  105. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Application.php Prevent unserialization

  106. joind.in/talk/4b6f9 @SammyK #LonghornPHP •Ensures one & only one instance •Global

    access (static function) •Initialization on first access
  107. joind.in/talk/4b6f9 @SammyK #LonghornPHP Case study Download CSV & calculate CLI

    View the report HTTP Endpoint
  108. joind.in/talk/4b6f9 @SammyK #LonghornPHP We get to make our final bootstrap

  109. joind.in/talk/4b6f9 @SammyK #LonghornPHP public/index.php

  110. joind.in/talk/4b6f9 @SammyK #LonghornPHP Eh?

  111. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Application.php However you register service providers into

    the container (different DI containers have their own API)
  112. joind.in/talk/4b6f9 @SammyK #LonghornPHP Why not in constructor?

  113. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Application.php

  114. joind.in/talk/4b6f9 @SammyK #LonghornPHP Install a router $ composer require nikic/fast-route

    (Choose your poison)
  115. joind.in/talk/4b6f9 @SammyK #LonghornPHP service provider Make a routing Pimple syntax

    - mileage my vary
  116. joind.in/talk/4b6f9 @SammyK #LonghornPHP Register in container src/Application.php

  117. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Router.php

  118. joind.in/talk/4b6f9 @SammyK #LonghornPHP Ugly A.F. src/routes.php

  119. joind.in/talk/4b6f9 @SammyK #LonghornPHP Different project, same component src/routes.php

  120. joind.in/talk/4b6f9 @SammyK #LonghornPHP public/index.php run We got bootstrap Runs CLI

    Runs HTTP
  121. joind.in/talk/4b6f9 @SammyK #LonghornPHP We got boilerplate src/Router.php src/Console/Runner.php symfony/console nikic/fast-route

  122. joind.in/talk/4b6f9 @SammyK #LonghornPHP Still not convinced?

  123. joind.in/talk/4b6f9 @SammyK #LonghornPHP What about Legacy

  124. joind.in/talk/4b6f9 @SammyK #LonghornPHP Why would you go bare? It’s a

    skill you can use for legacy apps
  125. joind.in/talk/4b6f9 @SammyK #LonghornPHP I’ll just rewrite this in x framework…

  126. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  127. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  128. joind.in/talk/4b6f9 @SammyK #LonghornPHP $ git add .

  129. joind.in/talk/4b6f9 @SammyK #LonghornPHP $ git commit -m \ “Stuff &

  130. joind.in/talk/4b6f9 @SammyK #LonghornPHP $ git push \ origin HEAD

  131. joind.in/talk/4b6f9 @SammyK #LonghornPHP $ git push \ production \ master

  132. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  133. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  134. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  135. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  136. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  137. joind.in/talk/4b6f9 @SammyK #LonghornPHP Legacy

  138. joind.in/talk/4b6f9 @SammyK #LonghornPHP Greenfield

  139. joind.in/talk/4b6f9 @SammyK #LonghornPHP I’ll just rewrite this in x framework…

  140. joind.in/talk/4b6f9 @SammyK #LonghornPHP We treat Legacy Greenfield & Totes samezies

    *except routing
  141. joind.in/talk/4b6f9 @SammyK #LonghornPHP Route exists? Not found Router Yes No

    Code 404
  142. joind.in/talk/4b6f9 @SammyK #LonghornPHP Route exists? Legacy router New router Yes

    No New code
  143. joind.in/talk/4b6f9 @SammyK #LonghornPHP app/webroot/index.php Old CakePHP bootstrap file

  144. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/bootstrap.php Same as public/index.php for HTTP

  145. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Router.php

  146. joind.in/talk/4b6f9 @SammyK #LonghornPHP tests? What about

  147. joind.in/talk/4b6f9 @SammyK #LonghornPHP Install PHPUnit $ composer require phpunit/phpunit --dev

  148. joind.in/talk/4b6f9 @SammyK #LonghornPHP phpunit.xml

  149. joind.in/talk/4b6f9 @SammyK #LonghornPHP tests/bootstrap.php

  150. joind.in/talk/4b6f9 @SammyK #LonghornPHP src/Application.php

  151. joind.in/talk/4b6f9 @SammyK #LonghornPHP Run the test suite $ ./vendor/bin/phpunit

  152. joind.in/talk/4b6f9 @SammyK #LonghornPHP How to choose your components

  153. joind.in/talk/4b6f9 @SammyK #LonghornPHP Use more than one framework #1

  154. joind.in/talk/4b6f9 @SammyK #LonghornPHP Search packagist.org #2 (Make sure it has

    good docs & is actively maintained)
  155. joind.in/talk/4b6f9 @SammyK #LonghornPHP experiments Try some

  156. joind.in/talk/4b6f9 @SammyK #LonghornPHP 100% middleware My next experiment: (I could

    totes use Zend Expressive or just go bare)
  157. joind.in/talk/4b6f9 @SammyK #LonghornPHP pros? framework ‘member the

  158. joind.in/talk/4b6f9 @SammyK #LonghornPHP Framework pros Crazy fast to get started

    …but you’ll get faster at going bare
  159. joind.in/talk/4b6f9 @SammyK #LonghornPHP Framework pros to maintain …most the time

    it’s really not that bad No bootstrap & boilerplate code
  160. joind.in/talk/4b6f9 @SammyK #LonghornPHP Framework pros The code is …so are

    the components you use when going bare battle tested
  161. joind.in/talk/4b6f9 @SammyK #LonghornPHP Framework pros Great …so are the components

    you use when going bare documentation
  162. joind.in/talk/4b6f9 @SammyK #LonghornPHP Framework pros Makes you more …going bare

    is a marketable skill marketable
  163. joind.in/talk/4b6f9 @SammyK #LonghornPHP Framework pros They are often …in many

    contexts going bare is more pragmatic pragmatic
  164. joind.in/talk/4b6f9 @SammyK #LonghornPHP myths? Did we bust the

  165. joind.in/talk/4b6f9 @SammyK #LonghornPHP #1 You must write everything from scratch

    Nope, use components
  166. joind.in/talk/4b6f9 @SammyK #LonghornPHP #2 You’re inherently anti- framework or anti-convention

    Nope, frameworks are great for most greenfield projects
  167. joind.in/talk/4b6f9 @SammyK #LonghornPHP #3 You’ll spend most of your time

    on bootstrapping instead of on domain code It takes a little longer at first but you’ll get faster with practice
  168. joind.in/talk/4b6f9 @SammyK #LonghornPHP #4 You must be an architecture astronaut

    Going bare is more pragmatic for legacy codebases
  169. joind.in/talk/4b6f9 @SammyK #LonghornPHP #5 You like pain No, we just

    like to improve our skills
  170. joind.in/talk/4b6f9 @SammyK #LonghornPHP

  171. joind.in/talk/4b6f9 @SammyK #LonghornPHP Remember: It’s all about tradeoffs.

  172. joind.in/talk/4b6f9 @SammyK #LonghornPHP Resources

  173. joind.in/talk/4b6f9 @SammyK #LonghornPHP Create a PHP application without a framework

    Patrick Louys https://github.com/PatrickLouys/no- framework-tutorial
  174. joind.in/talk/4b6f9 @SammyK #LonghornPHP Refactoring Martin Fowler

  175. joind.in/talk/4b6f9 @SammyK #LonghornPHP <3 frameworks I I also <3 my

    skill for Going Bare
  176. Sammy Kaye Powers Thanks! /talk/4b6f9 @SammyK SammyK.me Host of @PHPRoundtable

    Open source @DatadogHQ