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

More Decks by Jonathan Reinink

Other Decks in Technology


  1. None
  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.
  3. None
  4. We're in the middle of a PHP Renaissance.

  5. We're seeing a huge shift to creating smaller pieces of

    focused, reusable "framework agnostic" code.
  6. What exactly does framework agnostic mean?

  7. Code that works independent of frameworks.

  8. It’s about interoperability.

  9. Framework agnostic does not mean framework intolerant.

  10. Why is framework agnostic code important?

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

    for the job.
  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
  13. Framework agnostic code is also more reusable than framework specific

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

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

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

    quality code increases.
  17. We’re seeing a future where the various PHP communities actively

    share code with one another.
  18. So, why then are we using framework specific code?

  19. Because we sort of had to.

  20. PHP was first released in 1995.

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

  22. Routing Templating Database Abstraction Validation Session Handling Error Management Authentication

    Caching Request Processing Responses Sending
  23. Developers starting writing new, focused PHP libraries.

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

  25. So we manually downloaded zip files.

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

  27. But…PEAR had some issues.

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

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

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

  31. Frameworks allowed us to get work done quickly.

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

    Agavi, ezComponents
  33. However, frameworks were only a bandaid solution to the code

    sharing problem.
  34. What if the framework didn't have some other functionality you

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

  36. We continued to download zip files. :(

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

    larger PHP community.
  38. Then things changed.

  39. 1994 - 2004: 2005 - 2012: 2013 - Future: Vanilla

    PHP Frameworks Packages
  40. None
  41. Unlike PEAR, Composer got a LOT of things right.

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

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

  44. Packagist, the official Composer package repository, now serves well over

    100 million package installs per month.
  45. Developers benefit from faster release cycles and a wealth of

    packages to choose from.
  46. Composer gave us more than easy package installation, it also

    gave us interoperability.
  47. Composer let us cherry pick code (packages) without all the

    pain of downloading zip files.
  48. None
  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)
  50. Their very first recommendation was an autoloading standard called PSR-0.

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

    code more possible.
  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 = []); }
  53. PSR-7: HTTP message interfaces.


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

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

  57. www.php-fig.org

  58. So, do we still need frameworks?

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

  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)
  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.”
  62. Frameworks no longer have to be everything to everyone.

  63. “Frameworks dictate architecture, handle your bootstrapping and essentially give you

    a set of lines to color inside.” — Phil Sturgeon
  64. Frameworks are now the glue between reusable framework agnostic packages.

  65. Need something your framework doesn’t offer? No worries, just: >

    composer require the/package
  66. Even frameworks are now being built using framework agnostic code.

  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)
  68. Don’t be afraid to pull in components from other frameworks.

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

  70. "You will probably see more use-case specific skeletons come into

    the Zend Framework world.” — Rob Allen
  71. "Lumen 5.2.0 marks a shift to exclusively focusing on stateless

    APIs with Lumen for better definition between two frameworks.” - Taylor Otwell
  72. What will happen to bundles/plugins/ modules?

  73. None
  74. Puli aims to replace "bundles", "plugins", "modules" and similar specialized

    packages of different frameworks with one generic, framework independent solution.
  75. puli.io https://www.youtube.com/watch?v=nRqwGGROvfw

  76. How to choose a framework agnostic package.

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

  78. Look for packages with an existing track record.

  79. Beware of the framework specific wrapper package.

  80. Learn to write simple service providers.

  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') ); }); } }
  82. How to create a framework agnostic package.

  83. Remove all framework specific dependencies.

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

    $value = strpos($haystack, $needle) !== false;
  85. { "name": "your-awesome/package", "require": { "illuminate/support": "^5.2", } }

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

  87. Use abstractions and existing interfaces wherever possible.

  88. File system: Flysystem Intervention GD ImageMagick Image processing: Local Azure

    AWS Dropbox FTP SFTP Memory Rackspace
  89. HTTP Messages: Logging: DI Containers: PSR-7 PSR-3 container-interop

  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); } ), ]);
  91. Offer framework specific support for your package using service providers.

  92. None
  93. None
  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/" } } }
  95. If you’re a maintainer of a framework specific package, please

    consider making it framework agnostic.
  96. It’s good for package maintainers. It’s good for other developers.

    It’s good for frameworks. It’s good for PHP.
  97. Thanks! Follow me on Twitter at @reinink. Rate this talk