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

How to write better Symfony Bundles

How to write better Symfony Bundles

How to split bundles into smallers ones and let them depend. Also many smaller tipps and tricks you may not have seen yet.

Julius Beckmann

April 01, 2014
Tweet

More Decks by Julius Beckmann

Other Decks in Technology

Transcript

  1. Julius Beckmann (twitter|github).com/h4cc "A bundle is a directory that has

    a well-defined structure and can host anything from classes to controllers and web resources." http://symfony.com/doc/current/cookbook/bundles/best_practices.html
  2. Julius Beckmann (twitter|github).com/h4cc YourApp\WebBundle • For Browsers • Controller •

    Forms • Validations • Templates • Translations YourApp\ApiBundle • For API users like Mobile Apps • REST Controller • Serialization • Soap
  3. Julius Beckmann (twitter|github).com/h4cc Slim Controller • No Logic in Controller

    • Keep Logic in Services • Just Request/Response wrapper
  4. Julius Beckmann (twitter|github).com/h4cc Events in Controllers • Decoupling via Events

    • Decoupling between bundles • Intercept/Manipulate actions • Less Controller dependencies
  5. Julius Beckmann (twitter|github).com/h4cc Controller as Services • Instanciation by DI,

    not Symfony • Clear dependencies • Can be tested easily • Can be manipulated via DI • Need little more effort • "Controller" contains just shortcuts
  6. Julius Beckmann (twitter|github).com/h4cc • Very easy to use, great for

    Cronjobs • Reuse logic from services Write Commands
  7. Julius Beckmann (twitter|github).com/h4cc • Differ required and optional deps ➔

    __construct($required) ➔setOptional($optional) • Use private/public • Use parameters for classes parameters: my_mailer.class: Acme\HelloBundle\Mailer services: my_mailer: class: "%my_mailer.class%" DI Tipps
  8. Julius Beckmann (twitter|github).com/h4cc Alias global Services • "my_app.doctrine" alias for

    "doctrine" • "my_app.logger" alias for "logger" • Can be changed externally
  9. Julius Beckmann (twitter|github).com/h4cc • Dependency Injection via Annotations ✔ Faster

    development possible ✔ DI config "where it's used" ➔ Cluttering DI over code ➔ Testing DI is harder ➔ Magic hard to test ➔ Transparent code generation (!) JMS/DiExtraBundle
  10. Julius Beckmann (twitter|github).com/h4cc Use predefined Responses • Response • JsonResponse

    • BinaryFileResponse • RedirectResponse • StreamedResponse
  11. Julius Beckmann (twitter|github).com/h4cc • Definition of possible parameters • Using

    default values • Validation integrated • Changeable in dev/prod/test • "php app/console config:dump-reference MyApp " • Extension moves values to DI Write a Configuration
  12. Julius Beckmann (twitter|github).com/h4cc • Consider XML for services.xml • Support

    in IDE • Highlighting & Validation Prefer XML over YML
  13. Julius Beckmann (twitter|github).com/h4cc • Skip large SQL files • Directly

    define entites • Integrate in CI/CD Use DataFixtures
  14. Julius Beckmann (twitter|github).com/h4cc Unit Tests • Fast; No context; Idempotent

    • Generate coverage as a tool • Testing only units Functional Tests • Using context (Db, Caches, ...) • Can be slower • Testing functionality Separate Testing
  15. Julius Beckmann (twitter|github).com/h4cc SQLite can be faster • Create SQLite

    DB from Fixtures • Copy SQLite DB • Run Test • Revert DB to copy Mock external behaviour • Create Mock Service Class • Overwrite Services in config_test.yml Functional Testing
  16. Julius Beckmann (twitter|github).com/h4cc Install via composer Use Annotations: @covers My\Service::calculateBar

    @expectedException \RuntimeException @expectedExceptionMessage "FooBar" @dataProvider getTestInputs PHPUnit Hints
  17. Julius Beckmann (twitter|github).com/h4cc require Only what you use directly Not

    what others may need require-dev Librarys you use Tools you use (h4cc/phpqatools) Composer config