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

Framework agnostic packages for the win (SkiPHP 2016)

Framework agnostic packages for the win (SkiPHP 2016)

Jonathan Reinink

January 15, 2016
Tweet

More Decks by Jonathan Reinink

Other Decks in Technology

Transcript

  1. View Slide

  2. Jonathan Reinink
    Software developer from Canada.
    Been writing PHP for over 15 years.
    Marketing agency for over a decade.
    Started contract development this year.
    I <3 open source.

    View Slide

  3. View Slide

  4. We're in the middle of
    a PHP Renaissance.

    View Slide

  5. We're seeing a huge shift to
    creating smaller pieces of
    focused, reusable
    "framework agnostic" code.

    View Slide

  6. What exactly does
    framework agnostic mean?

    View Slide

  7. Code that works
    independent of
    frameworks.

    View Slide

  8. It’s about
    interoperability.

    View Slide

  9. Framework agnostic
    does not mean
    framework intolerant.

    View Slide

  10. Why is framework
    agnostic code important?

    View Slide

  11. Framework agnostic code
    allows you to choose the
    best library for the job.

    View Slide

  12. "You should be using best of
    breed stuff, you shouldn't have to
    use the stuff that came with your
    framework if there is better stuff
    out there; it should just drop in.”
    — Rob Allen

    View Slide

  13. Framework agnostic code
    is also more reusable than
    framework specific code.

    View Slide

  14. Reusable code is code
    we don't have to write.

    View Slide

  15. Creating reusable code is
    key to the continued
    success of PHP.

    View Slide

  16. As software become
    increasingly more complex,
    our reliance on existing,
    quality code increases.

    View Slide

  17. We’re seeing a future
    where the various PHP
    communities actively share
    code with one another.

    View Slide

  18. So, why then are we
    using framework
    specific code?

    View Slide

  19. Because we sort of had to.

    View Slide

  20. PHP was first
    released in 1995.

    View Slide

  21. PHP had a decent
    standard library, but
    pieces were missing.

    View Slide

  22. Routing
    Templating
    Database Abstraction
    Validation
    Session Handling
    Error Management
    Authentication
    Caching
    Request Processing
    Responses Sending

    View Slide

  23. Developers starting
    writing new, focused
    PHP libraries.

    View Slide

  24. But…we had no easy
    way to share them.

    View Slide

  25. So we manually
    downloaded zip files.

    View Slide

  26. Introducing PEAR:
    PHP first attempt at
    a package manager.

    View Slide

  27. But…PEAR had
    some issues.

    View Slide

  28. The community gave up
    on PEAR, and started
    using frameworks instead.

    View Slide

  29. Frameworks were
    easy to download,
    and they just worked.

    View Slide

  30. Frameworks came with
    almost everything needed
    for the average project.

    View Slide

  31. Frameworks allowed us
    to get work done quickly.

    View Slide

  32. 2005 became the year
    of PHP frameworks.
    Symfony, CakePHP, Solar, Agavi, ezComponents

    View Slide

  33. However, frameworks were
    only a bandaid solution to
    the code sharing problem.

    View Slide

  34. What if the framework
    didn't have some other
    functionality you needed?

    View Slide

  35. Naturally, frameworks
    grew to accommodate a
    wide range of use cases.

    View Slide

  36. We continued to
    download zip files. :(

    View Slide

  37. This led to very distinct siloed
    micro communities within
    the larger PHP community.

    View Slide

  38. Then things changed.

    View Slide

  39. 1994 - 2004:
    2005 - 2012:
    2013 - Future:
    Vanilla PHP
    Frameworks
    Packages

    View Slide

  40. View Slide

  41. Unlike PEAR, Composer
    got a LOT of things right.

    View Slide

  42. Downloaded packages.
    Resolved their dependencies.
    Autoloaded classes.

    View Slide

  43. Composer was an overnight
    success, and became
    mainstream in 2013.

    View Slide

  44. Packagist, the official Composer
    package repository, now serves
    well over 100 million package
    installs per month.

    View Slide

  45. Developers benefit from
    faster release cycles and
    a wealth of packages to
    choose from.

    View Slide

  46. Composer gave us more
    than easy package
    installation, it also gave
    us interoperability.

    View Slide

  47. Composer let us cherry
    pick code (packages)
    without all the pain of
    downloading zip files.

    View Slide

  48. View Slide

  49. “We're a group of established
    PHP projects whose goal is to talk
    about commonalities between
    our projects and find ways we can
    work better together.”
    (PHP-FIG goal)

    View Slide

  50. Their very first
    recommendation was an
    autoloading standard
    called PSR-0.

    View Slide

  51. The PHP-FIG continues
    to develop standards that
    make framework agnostic
    code more possible.

    View Slide

  52. namespace Psr\Log;
    interface LoggerInterface
    {
    public function emergency($message, array $context = []);
    public function alert($message, array $context = []);
    public function critical($message, array $context = []);
    public function error($message, array $context = []);
    public function warning($message, array $context = []);
    public function notice($message, array $context = []);
    public function info($message, array $context = []);
    public function debug($message, array $context = []);
    public function log($level, $message, array $context = []);
    }

    View Slide

  53. PSR-7: HTTP message
    interfaces.

    View Slide

  54. $_SERVER
    $_GET
    $_POST
    $_FILES
    $_SESSION
    $_COOKIE

    View Slide

  55. $response = (new Response())
    ->withStatus(200, 'OK')
    ->withHeader('Content-Type', 'application/json')
    ->withBody($body);

    View Slide

  56. Expect to see more of
    PSR-7 in 2016.

    View Slide

  57. www.php-fig.org

    View Slide

  58. So, do we still need
    frameworks?

    View Slide

  59. In the time of packages,
    the purpose of
    frameworks is changing.

    View Slide

  60. “A huge part of the PHP Renaissance
    has been due to the advent of
    Composer, which has simplified
    dependency management, and led to
    tens of thousands of standalone
    libraries and packages.” (continued)

    View Slide

  61. “As such, frameworks, while still popular,
    are often being eschewed for
    homemade, application-specific
    frameworks made of commodity
    components. Frameworks simply cannot
    ignore this trend, and decoupling should
    become the norm going forward.”

    View Slide

  62. Frameworks no longer
    have to be everything
    to everyone.

    View Slide

  63. “Frameworks dictate architecture,
    handle your bootstrapping and
    essentially give you a set of lines
    to color inside.”
    — Phil Sturgeon

    View Slide

  64. Frameworks are now the glue
    between reusable framework
    agnostic packages.

    View Slide

  65. Need something your
    framework doesn’t offer?
    No worries, just:
    > composer require the/package

    View Slide

  66. Even frameworks are now
    being built using
    framework agnostic code.

    View Slide

  67. “Today, even competing frameworks
    make liberal use of each other’s
    components, because the PHP
    community at large has adopted a culture
    of sharing and of working together.”
    — Heroku (blog)

    View Slide

  68. Don’t be afraid to pull
    in components from
    other frameworks.

    View Slide

  69. We’re seeing an
    increase in framework
    specialization.

    View Slide

  70. "You will probably see more
    use-case specific skeletons
    come into the Zend
    Framework world.”
    — Rob Allen

    View Slide

  71. "Lumen 5.2.0 marks a shift to
    exclusively focusing on
    stateless APIs with Lumen for
    better definition between two
    frameworks.”
    - Taylor Otwell

    View Slide

  72. What will happen to
    bundles/plugins/
    modules?

    View Slide

  73. View Slide

  74. Puli aims to replace "bundles",
    "plugins", "modules" and similar
    specialized packages of different
    frameworks with one generic,
    framework independent solution.

    View Slide

  75. puli.io
    https://www.youtube.com/watch?v=nRqwGGROvfw

    View Slide

  76. How to choose a
    framework agnostic
    package.

    View Slide

  77. Don't reach for the
    framework specific
    package first.

    View Slide

  78. Look for packages with
    an existing track record.

    View Slide

  79. Beware of the framework
    specific wrapper package.

    View Slide

  80. Learn to write simple
    service providers.

    View Slide

  81. use Illuminate\Support\ServiceProvider;
    use Services_Twilio;
    class TwilioServiceProvider extends ServiceProvider
    {
    public function register()
    {
    $this->app->singleton(Services_Twilio::class, function ($app) {
    return new Services_Twilio(
    env('TWILIO_SID'),
    env('TWILIO_TOKEN')
    );
    });
    }
    }

    View Slide

  82. How to create a
    framework agnostic
    package.

    View Slide

  83. Remove all framework
    specific dependencies.

    View Slide

  84. // Framework specific
    $value = str_contains($haystack, $needle);
    // Framework agnostic
    $value = strpos($haystack, $needle) !== false;

    View Slide

  85. {
    "name": "your-awesome/package",
    "require": {
    "illuminate/support": "^5.2",
    }
    }

    View Slide

  86. Don’t over commit, focus
    on doing one thing well.

    View Slide

  87. Use abstractions and
    existing interfaces
    wherever possible.

    View Slide

  88. File system: Flysystem
    Intervention
    GD
    ImageMagick
    Image processing:
    Local
    Azure
    AWS
    Dropbox
    FTP
    SFTP
    Memory
    Rackspace

    View Slide

  89. HTTP Messages:
    Logging:
    DI Containers:
    PSR-7
    PSR-3
    container-interop

    View Slide

  90. $server = League\Glide\ServerFactory::create([
    // File system abstraction
    'source' => new Filesystem(new Local('path')),
    // Image processor abstraction
    'driver' => 'imagick',
    // HTTP messages interface (PSR-7)
    'response' => new PsrResponseFactory(
    new Response(),
    function ($stream) {
    return new Stream($stream);
    }
    ),
    ]);

    View Slide

  91. Offer framework specific
    support for your package
    using service providers.

    View Slide

  92. View Slide

  93. View Slide

  94. {
    "name": "league/glide-cake",
    "description": "Glide adapter for CakePHP",
    "require": {
    "cakephp/cakephp": "^3.0",
    "league/glide": "^1.0"
    },
    "require-dev": {
    "phpunit/phpunit": "^4.0"
    },
    "autoload": {
    "psr-4": {
    "League\\Glide\\": "src/"
    }
    }
    }

    View Slide

  95. If you’re a maintainer of a
    framework specific package,
    please consider making it
    framework agnostic.

    View Slide

  96. It’s good for package maintainers.
    It’s good for other developers.
    It’s good for frameworks.
    It’s good for PHP.

    View Slide

  97. Thanks!
    Follow me on Twitter at @reinink.
    Rate this talk https://joind.in/16658.

    View Slide