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

Symfony Internals

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Symfony Internals

PHPBenelux 2018

Avatar for Andreas Hucks

Andreas Hucks

January 27, 2018
Tweet

More Decks by Andreas Hucks

Other Decks in Programming

Transcript

  1. The Request $kernel = new Kernel($env, $debug); $request = Request::createFromGlobals();

    $response = $kernel->handle($request); $response->send();
  2. GetResponseEvent class GetResponseEvent extends KernelEvent { public function getResponse() {

    return $this->response; } public function setResponse(Response $response) { $this->response = $response; $this->stopPropagation(); } kernel.request
  3. RouterListener /** * @Route(path="/books/{id}", name="book_show") */ $params = [ '_controller'

    => ‘App\Controller\BookController::showAction’, '_route' => 'book_show', '_route_params' => [ 'id' => '37' ], 'id' => ’37' ]; kernel.request
  4. Customize! • Content Negotiation - Parse headers and add attribute

    • Verify signed Cookies • Redirects based on arbitrary criteria • Custom Locale stuff • … ?
  5. FilterControllerEvent class FilterControllerEvent extends KernelEvent { public function getController() {

    return $this->controller; } public function setController(callable $controller) { $this->controller = $controller; } kernel.controller
  6. ControllerListener class ControllerListener implements EventSubscriberInterface { public function __construct(Reader $reader)

    { $this->reader = $reader; } public function onKernelController(FilterControllerEvent $event) { $controller = $event->getController(); // read annotations for class and method $request = $event->getRequest(); foreach ($configurations as $key => $attributes) { $request->attributes->set($key, $attributes); } kernel.controller
  7. GetResponseForControllerResultEvent class GetResponseForControllerResultEvent extends GetResponseEvent { public function getControllerResult() {

    return $this->controllerResult; } public function setControllerResult($controllerResult) { $this->controllerResult = $controllerResult; } kernel.view
  8. TemplateListener public function onKernelView( GetResponseForControllerResultEvent $event ) { /* @var

    Template $template */ $request = $event->getRequest(); $template = $request->attributes->get(‘_template'); // … $event->setResponse( new Response( $this->twig->render($template->getTemplate()), $parameters ) ); kernel.view
  9. Customize! • Auto serializing and encoding for web service responses

    • Together with kernel.controller: 
 Action Domain Responder, other patterns?
  10. ExceptionListener public function onKernelException( GetResponseForExceptionEvent $event ) { $exception =

    $event->getException(); $request = $event->getRequest(); $this->logException($exception kernel.exception
  11. Customize! • Customize for every exception type you like •

    Redirect for some errors • “were you looking for…” suggestions on 404 pages • Custom alerts • … ?
  12. FilterResponseEvent class FilterResponseEvent extends KernelEvent { public function getResponse() {

    return $this->response; } public function setResponse(Response $response) { $this->response = $response; } kernel.response
  13. SaveSessionListener $session = $event->getRequest()->getSession(); if ($session && $session->isStarted()) { $session->save();

    $event->getResponse() ->setPrivate() ->setMaxAge(0) ->headers->addCacheControlDirective('must-revalidate'); } kernel.response
  14. Container & Cache protected function getRouterService() { $this->services[‘router'] = $instance

    = new \Symfony\Bundle\…\Router( $this, ‘/app/config/routing_dev.yml' ) // [snip] return $instance; }
  15. Container & Cache Cache class for this request? Does it

    exists? require() it yes Build Container no
  16. Container & Cache Cache class for this request? Does it

    exists? require() it yes Build Container no
  17. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers (quite a few)
  18. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  19. Registering Bundles public function registerBundles() { $bundles = [ new

    Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\TwigBundle\TwigBundle(), // [snip] ]; return $bundles; }
  20. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  21. Registering Extensions protected function prepareContainer(ContainerBuilder $container) { $extensions = array();

    foreach ($this->bundles as $bundle) { if ($extension = $bundle->getContainerExtension()) { $container->registerExtension($extension); $extensions[] = $extension->getAlias(); } // [snip] }
  22. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  23. Register Project-Level Container Config public function registerContainerConfiguration( LoaderInterface $loader )

    { $loader->load( $this->getRootDir(). ’/config/config_’.$this->getEnvironment().'.yml' ); }
  24. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  25. Extensions class TwigExtension extends Extension { public function load(array $configs,

    ContainerBuilder $container) { $loader = new XmlFileLoader( $container, new FileLocator(__DIR__.’/../Resources/config') ); $loader->load('twig.xml');
  26. Customize! • Load config files • Do not load config

    files depending on parameter • Set Parameters, manipulate parameters • BETTER NOT manipulate services (they are not complete at this point, see next slides)
  27. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  28. Compiler Passes public function process(ContainerBuilder $container) { if (!$container->has('app.myservice')) {

    return; } $definition = $container->findDefinition( 'app.myservice' ); // find formatter service $definition->addMethodCall( 'addFormatter', array(new Reference($formatterId)) ); }
  29. (A few) Compiler Passes • ServiceLocatorTagPass • DecoratorServicePass • ResolveParameterPlaceHoldersPass

    • ResolveFactoryClassPass • ResolveNamedArgumentsPass • AutowirePass • RemovePrivateAliasesPass • ReplaceAliasByActualDefinitionPass • RemoveAbstractDefinitionsPass • InlineServiceDefinitionsPass • RemoveUnusedDefinitionsPass
  30. (A few) Compiler Passes • ServiceLocatorTagPass • DecoratorServicePass • ResolveParameterPlaceHoldersPass

    • ResolveFactoryClassPass • ResolveNamedArgumentsPass • AutowirePass • RemovePrivateAliasesPass • ReplaceAliasByActualDefinitionPass • RemoveAbstractDefinitionsPass • InlineServiceDefinitionsPass • RemoveUnusedDefinitionsPass
  31. Customize! • Add method calls to services based on tags

    • Manipulate services that depend on the full service config
  32. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  33. Dump Container protected function dumpContainer( ConfigCache $cache, ContainerBuilder $container, $class,

    $baseClass ) { $dumper = new PhpDumper($container); $content = $dumper->dump(/*…*/);
  34. Container Build Register Bundles Register Extensions & Compiler Passes Register

    Project Config Run Extensions Run compiler Passes Dump Container Run Cache Warmers
  35. Cache Warmers public function warmUp($cacheDir) { $filesystem = new Filesystem();

    $templates = array(); foreach ($this->finder->findAllTemplates() as $template) { // [snip] } // [snip] $this->writeCacheFile($cacheDir.’/templates.php', // [snip] }
  36. Customize! • You have full access to services, the container

    in ready • Create custom caches your application needs • Prefetch and cache data from external sources