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

Play PHP Like a Puzzle

Play PHP Like a Puzzle

PHP development used to involve lots of handcrafted code. Today it's more like playing a puzzle: Find the pieces that you need, put them together and voilà.

This game is about Composer: Do you know the most powerful puzzle pieces? But there's more. With PSR-7, Puli and standardized DI configuration, puzzlers have a new ace up their sleeves.

Bernhard Schussek

June 24, 2016
Tweet

More Decks by Bernhard Schussek

Other Decks in Programming

Transcript

  1. Bernhard Schussek · webmozart.io 1/114 https://www.flickr.com/photos/emmacherry/2207748365 (CC BY-NC 2.0) Play

    PHP Like A Puzzle Bernhard Schussek (@webmozart) Dutch PHP Conference 2016, Amsterdam
  2. Bernhard Schussek · webmozart.io 6/114 Bernhard Schussek PHP Trainer and

    Coach Symfony Architecture Coding Practices webmozart.io
  3. Bernhard Schussek · webmozart.io 10/114 Contributing Factors • Organizational Factors

    — developer skills — work/life balance — work atmosphere — … • Technical Factors — tools — ready-made solutions
  4. Bernhard Schussek · webmozart.io 18/114 $ composer require league/tactician Using

    version ^1.0 for league/tactician ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing league/tactician (v1.0.2) Downloading: 100% Writing lock file Generating autoload files Step 3: Install in Your Project Composer
  5. Bernhard Schussek · webmozart.io 22/114 use Monolog\Logger; use League\Tactician\Logger\LoggerMiddleware; $logger

    = new Logger('my_app'); $commandBus = new CommandBus([ new LoggerMiddleware($formatter, $logger), // ... ]); PSR-3 Logging
  6. Bernhard Schussek · webmozart.io 34/114 Abilities of Module Systems •

    DI container configuration • database configuration • MVC support • file loading • web assets • migrations (automated upgrades) • …
  7. Bernhard Schussek · webmozart.io 43/114 https://www.flickr.com/photos/picturesfromwords/9539461080 (CC BY-NC 2.0) Goal:

    Interoperable Modules for PHP https://www.flickr.com/photos/emmacherry/2207748365 (CC BY-NC 2.0)
  8. Bernhard Schussek · webmozart.io 46/114 class MyServiceProvider implements ServiceProviderInterface {

    public function getServices() { return [ 'service_name' => function () { // create service } ]; } } Providing Services from Modules
  9. Bernhard Schussek · webmozart.io 47/114 'post_repository' => function () {

    return new PDOPostRepository(); } $container = new Pimple(); $container->addServiceProvider(new PDOServiceProvider()) $container->addServiceProvider(new MyServiceProvider()); $repo = $container->get('post_repository'); Example: PDOPostRepository
  10. Bernhard Schussek · webmozart.io 48/114 'post_repository' => function (ContainerInterface $c)

    { return new PDOPostRepository( $c->get('pdo') ); } Service Injection
  11. Bernhard Schussek · webmozart.io 49/114 'pdo' => function ($c, callable

    $getPrevious) { return new PDOLogger( $getPrevious(), $c->get('logger') ); } Service Decoration
  12. Bernhard Schussek · webmozart.io 50/114 'pdo.options' => function ($c, callable

    $getPrevious) { return array_replace($getPrevious(), [ 'database_name' => 'mydb', ]); } Service Parameters
  13. Bernhard Schussek · webmozart.io 51/114 'twig_extensions' => function ($c, callable

    $getPrevious return array_merge($getPrevious(), [ new MyTwigExtension(), ]); } Service Lists
  14. Bernhard Schussek · webmozart.io 52/114 PostRepository::class => function (ContainerInterface $c

    return new PDOPostRepository( $c->get(PDO::class) ); } $repo = $container->get(PostRepository::class); Interfaces as Service Names
  15. Bernhard Schussek · webmozart.io 57/114 Tech Demos Doctrine DBAL Module

    Doctrine Annotations Module Glide Module PSR-6 to Doctrine cache bridge module Slim-framework Module Stash Module Stratigility Module Twig Module Whoops PSR-7 Middleware Module
  16. Bernhard Schussek · webmozart.io 66/114 PHP Code Resource Files puli.json

    Module Configuration composer.json Installation Instructions Puli Module
  17. Bernhard Schussek · webmozart.io 74/114 puli.json (in the batman/blog module)

    { "resources": { "/batman/blog": "res" } } preview
  18. Bernhard Schussek · webmozart.io 80/114 $html = $this->render('/app/views/post.html'); Resource Access

    puli.json (in your application) { "resources": { "/app": "res" } }
  19. Bernhard Schussek · webmozart.io 82/114 PHP Code Resource Files Publish

    Assets public/ css/ style.min.css images/ background.png Module Document Root PHP Code Resource Files Module
  20. Bernhard Schussek · webmozart.io 84/114 Gulpfile.js var gulp = require('gulp'),

    puli = require('puli').load(); gulp.task('vendor', function () { puli.src('/batman/blog/public/**/*') .dest('res/public/blog'); });
  21. Bernhard Schussek · webmozart.io 85/114 Generate URLs var urls =

    require('puli-urls'); gulp.task('vendor', function () { puli.src('/batman/blog/public/**/*') .pipe(urls()) .dest('res/public/blog') .pipe(urls.mapping()) .dest('.puli/urls.json'); });
  22. Bernhard Schussek · webmozart.io 87/114 <img src="{{ asset_url('/batman/blog/public/bg.png') }}" <link

    href="{{ asset_url('../public/css/style.css') }}" Print URLs in Templates
  23. Bernhard Schussek · webmozart.io 88/114 body { background-image: asset_url("/res/public/bg.png"); //

    Relative paths background-image: asset_url("bg.png"); } Print URLs in CSS
  24. Bernhard Schussek · webmozart.io 94/114 { "provide": { "/app/routing.yml": "symfony/routing-yml",

    "/app/trans/*.xlf": "league/translation-xlf", "My\\AppServiceProvider": "Psr\\DI\\ServiceProviderInterface" } } puli.json (of your application or module)
  25. Bernhard Schussek · webmozart.io 95/114 $router = new Router($discovery); $translator

    = new Translator($discovery); $container = new Container($discovery); // ... Using the Modules
  26. Bernhard Schussek · webmozart.io 103/114 $container = new Container($discovery); $router

    = $container->get(Router::class); $controller = $router->getController('/hello/world'); $response = $controller->handle($request); Applications with Puli and PSR-11
  27. Bernhard Schussek · webmozart.io 117/114 Questions? Questions? Bernhard Schussek Bernhard

    Schussek @webmozart @webmozart https://www.flickr.com/photos/puliarfanita/7167723539 (CC BY 2.0) webmozart.io