$30 off During Our Annual Pro Sale. View Details »

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
Tweet

More Decks by Sammy Kaye Powers

Other Decks in Programming

Transcript

  1. Going Bare
    Writing the web
    without a framework
    Sammy Kaye Powers
    2019-05-03

    View Slide

  2. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Slides
    Get the
    joind.in/talk/4b6f9

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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.

    View Slide

  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)

    View Slide

  8. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Frameworks are a
    tool

    View Slide

  9. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Going bare is a
    skill
    (that you don’t get with a framework)

    View Slide

  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)

    View Slide

  11. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Myths
    about
    going
    frameworkless

    View Slide

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

    View Slide

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

    View Slide

  14. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Myth #3
    You’ll spend most of
    your time on
    boilerplate instead of
    on domain code

    View Slide

  15. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Myth #4
    You must be an
    architecture
    astronaut

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  23. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Pros
    boilerplate
    all the things
    You don’t have to Con
    but it can be a

    View Slide

  24. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Pros
    bootstrap &
    boilerplate
    code
    You don’t have to maintain

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Cons
    Cruft
    • Deployment takes longer
    • Upgrading pulls in all
    the new features

    View Slide

  34. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Cons
    tightly couple
    Easier to
    due to convenience

    View Slide

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

    View Slide

  36. 5.3

    View Slide

  37. 5.7
    2018-09-04

    View Slide

  38. View Slide

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

    View Slide

  40. View Slide

  41. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  45. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    When
    should you go bare?

    View Slide

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

    View Slide

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

    View Slide

  48. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    1%
    99%
    90%
    10%
    Go Bare Framwork
    Greenfield Legacy
    Going bare vs framework

    View Slide

  49. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    How
    do you go bare?

    View Slide

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

    View Slide

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

    View Slide

  52. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    That means writing all the things
    Router DBAL/ORM Dep Injection Logger

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  59. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    choose ur candy
    Going bare lets you
    Look at all
    those smarties!
    Yum!

    View Slide

  60. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    I like smarties

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  64. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    bag o’ candy
    A framework is like a
    Comes with
    licorice?
    Yuck!

    View Slide

  65. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    I don’t like licorice

    View Slide

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

    View Slide

  67. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Key:
    Get comfy with
    bootstrapping &
    boilerplate code
    It’s really
    not that bad

    View Slide

  68. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    examples
    Real-world

    View Slide

  69. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    conventions
    When going bare, there aren’t any
    …so this is a way,
    not the way

    View Slide

  70. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Greenfield
    Let’s start with

    View Slide

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

    & save
    to DB
    Show
    report
    Client’s server Our server

    View Slide

  72. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Case study
    Download CSV & calculate
    CLI
    View the report
    HTTP Endpoint

    View Slide

  73. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    coding domain
    in 5 mins
    Install framework &

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  78. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Start in the CLI
    (Just like when you use a framework!)

    View Slide

  79. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    1. Make an empty
    composer.json or…
    $ composer init

    View Slide

  80. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    2. Make a folder for
    domain code
    $ mkdir src

    View Slide

  81. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    3. Add autoloading
    $ composer \
    dumpautoload
    And then run…

    View Slide

  82. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Now just install your
    components &
    tie them together

    View Slide

  83. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Key:
    Get comfy with
    bootstrapping &
    boilerplate code
    It’s really
    not that bad

    View Slide

  84. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Case study
    Download CSV & calculate
    CLI
    View the report
    HTTP Endpoint

    View Slide

  85. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Install a
    console component
    $ composer require symfony/console
    (or maybe you like zendframework/zend-console)

    View Slide

  86. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    src/Console/Runner.php

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  95. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Install the
    DI container
    $ composer require pimple/pimple
    (Choose your poison)

    View Slide

  96. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Need to
    make
    singleton
    ready
    src/Application.php

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  100. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Singleton
    •Ensures one & only one instance
    •Global access (static function)
    •Initialization on first access

    View Slide

  101. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Fatal error: Call to private
    App\Application::__construct()
    src/Application.php

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  106. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    •Ensures one & only one instance
    •Global access (static function)
    •Initialization on first access

    View Slide

  107. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Case study
    Download CSV & calculate
    CLI
    View the report
    HTTP Endpoint

    View Slide

  108. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    We get to make our
    final bootstrap code!

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  112. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Why not
    in constructor?

    View Slide

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

    View Slide

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

    View Slide

  115. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    service provider
    Make a routing
    Pimple syntax - mileage my vary

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  124. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Why
    would you go bare?
    It’s a skill you can use
    for legacy apps

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  154. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Search
    packagist.org
    #2
    (Make sure it has good docs &
    is actively maintained)

    View Slide

  155. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    experiments
    Try some

    View Slide

  156. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    100%
    middleware
    My next experiment:
    (I could totes use Zend Expressive or just go bare)

    View Slide

  157. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    pros?
    framework
    ‘member the

    View Slide

  158. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Framework pros
    Crazy fast
    to get started
    …but you’ll get faster
    at going bare

    View Slide

  159. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Framework pros
    to maintain
    …most the time it’s
    really not that bad
    No bootstrap & boilerplate code

    View Slide

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

    View Slide

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

    View Slide

  162. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Framework pros
    Makes you more
    …going bare is a
    marketable skill
    marketable

    View Slide

  163. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Framework pros
    They are often
    …in many contexts
    going bare is more
    pragmatic
    pragmatic

    View Slide

  164. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    myths?
    Did we bust the

    View Slide

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

    View Slide

  166. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    #2 You’re inherently anti-
    framework or anti-convention
    Nope, frameworks
    are great for most
    greenfield projects

    View Slide

  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

    View Slide

  168. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    #4 You must be an architecture
    astronaut
    Going bare is more
    pragmatic for legacy
    codebases

    View Slide

  169. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    #5 You like pain
    No, we just like to
    improve our skills

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  173. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Create a PHP
    application without
    a framework
    Patrick Louys
    https://github.com/PatrickLouys/no-
    framework-tutorial

    View Slide

  174. joind.in/talk/4b6f9
    @SammyK #LonghornPHP
    Refactoring
    Martin Fowler

    View Slide

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

    View Slide

  176. Sammy
    Kaye
    Powers
    Thanks!
    /talk/4b6f9
    @SammyK
    SammyK.me
    Host of @PHPRoundtable
    Open source @DatadogHQ

    View Slide