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

Into the kernel and back

Into the kernel and back

A journey into the heart of the Symfony framework, explaining internals of the application and http kernels, including the rich event ecosystem.

Discover almost unlimited possibilities that come with the framework out of the box, and can be used to extend its default request handling.

Finally, learn how to leverage the kernel and the event dispatcher to migrate away from an Old School PHP Spaghetti Project™ to a modern Symfony based application.

http://www.symfonyday.pt/2014/

Jakub Zalas

March 08, 2014
Tweet

More Decks by Jakub Zalas

Other Decks in Technology

Transcript

  1. Into the kernel and back
    Jakub Zalas
    Lisbon, 8.03.2014

    View full-size slide

  2. Olá!
    I work @SensioLabsUK
    I tweet @jakub_zalas
    I code @jakzal

    View full-size slide

  3. HttpKernelInterface

    View full-size slide

  4. namespace Symfony\Component\HttpKernel;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    interface HttpKernelInterface
    {
    const MASTER_REQUEST = 1;
    const SUB_REQUEST = 2;
    /**
    * @return Response
    */
    public function handle(
    Request $request,
    $type = self::MASTER_REQUEST,
    $catch = true
    );
    }

    View full-size slide

  5. namespace Symfony\Component\HttpKernel;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    interface HttpKernelInterface
    {
    const MASTER_REQUEST = 1;
    const SUB_REQUEST = 2;
    /**
    * @return Response
    */
    public function handle(
    Request $request,
    $type = self::MASTER_REQUEST,
    $catch = true
    );
    }

    View full-size slide

  6. Request Response
    /hello/sfdaypt

    View full-size slide

  7. $response = $kernel->handle($request);

    View full-size slide

  8. use Symfony\Component\HttpFoundation\Request;
    $request = Request::createFromGlobals();
    $kernel = new SimpleKernel();
    $response = $kernel->handle($request);
    $response->send();

    View full-size slide

  9. use Symfony\Component\HttpKernel\HttpKernelInterface;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    class SimpleKernel implements HttpKernelInterface
    {
    public function handle(Request $request /*,...*/)
    {
    return new Response('Hello Portugal');
    }
    }

    View full-size slide

  10. use Symfony\Component\HttpKernel\HttpKernelInterface;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    class SimpleKernel implements HttpKernelInterface
    {
    public function handle(Request $request /*,...*/)
    {
    return new Response('Hello Portugal');
    }
    }

    View full-size slide

  11. Request Response
    callable  
    callable  
    callable  
    callable  
    /
    /hello/{name}
    /contact
    /events
    Router
    /hello/sfdaypt

    View full-size slide

  12. public function handle(Request $request /*,...*/)
    {
    $controller = $this->matchRequest($request);
    $response = call_user_func($controller):
    return $response;
    }
    private function matchRequest(Request $request)
    {
    $map = array(
    '/' => array(new Homepage(), 'indexAction'),
    '/contact' => array(new Contact(), 'formAction')
    );
    return $map[$request->getPathInfo()];
    }

    View full-size slide

  13. public function handle(Request $request /*,...*/)
    {
    $controller = $this->matchRequest($request);
    $response = call_user_func($controller):
    return $response;
    }
    private function matchRequest(Request $request)
    {
    $map = array(
    '/' => array(new Homepage(), 'indexAction'),
    '/contact' => array(new Contact(), 'formAction')
    );
    return $map[$request->getPathInfo()];
    }

    View full-size slide

  14. private function matchRequest(Request $request)
    {
    $routes = $this->getRoutes();
    $context = new RequestContext();
    $context->fromRequest($request);
    $urlMatcher = new UrlMatcher($routes, $context);
    return $urlMatcher->matchRequest($request);
    }
    private function getRoutes()
    {
    $routes = new RouteCollection();
    $routes->add('homepage', new Route('/',
    array('_controller' => 'Homepage::indexAction')));
    $routes->add('contact', new Route('/',
    array('_controller' => 'Contact::formAction')));
    return $routes;
    }

    View full-size slide

  15. private function matchRequest(Request $request)
    {
    $routes = $this->getRoutes();
    $context = new RequestContext();
    $context->fromRequest($request);
    $urlMatcher = new UrlMatcher($routes, $context);
    return $urlMatcher->matchRequest($request);
    }
    private function getRoutes()
    {
    $routes = new RouteCollection();
    $routes->add('homepage', new Route('/',
    array('_controller' => 'Homepage::indexAction')));
    $routes->add('contact', new Route('/',
    array('_controller' => 'Contact::formAction')));
    return $routes;
    }

    View full-size slide

  16. private function matchRequest(Request $request)
    {
    $routes = $this->getRoutes();
    $context = new RequestContext();
    $context->fromRequest($request);
    $urlMatcher = new UrlMatcher($routes, $context);
    return $urlMatcher->matchRequest($request);
    }
    private function getRoutes()
    {
    $routes = new RouteCollection();
    $routes->add('homepage', new Route('/',
    array('_controller' => 'Homepage::indexAction')));
    $routes->add('contact', new Route('/',
    array('_controller' => 'Contact::formAction')));
    return $routes;
    }

    View full-size slide

  17. hello:
    path: /hello/{name}
    defaults:
    _controller: 'DemoController::helloAction'

    View full-size slide

  18. private function getRoutes()
    {
    $locator = new FileLocator(array(__DIR__));
    $loader = new YamlFileLoader($locator);
    $routes = $loader->load('routes.yml');
    return $routes;
    }

    View full-size slide

  19. public function handle(Request $request /*,...*/)
    {
    // ['_controller' => 'Homepage::indexAction']
    $parameters = $this->matchRequest($request);
    // [new Homepage(), 'indexAction']
    $controller = ???
    $response = call_user_func($controller):
    return $response;
    }

    View full-size slide

  20. Controller resolver

    View full-size slide

  21. Request Response
    callable  
    callable  
    callable  
    callable  
    /
    /hello/{name}
    /contact
    /events
    Router
    /hello/sfdaypt
    Controller
    Resolver

    View full-size slide

  22. public function handle(Request $request /*,...*/)
    {
    $parameters = $this->matchRequest($request);
    $controller = $this->resolveController($parameters);
    $response = call_user_func($controller):
    return $response;
    }
    private function resolveController($parameters)
    {
    // i.e. Homepage::indexAction
    $controller = $parameters['_controller'];
    list($class, $method) = explode('::', $controller);
    $controller = new $class();
    return array($class, $method);
    }

    View full-size slide

  23. public function handle(Request $request /*,...*/)
    {
    $parameters = $this->matchRequest($request);
    $controller = $this->resolveController($parameters);
    $response = call_user_func($controller):
    return $response;
    }
    private function resolveController($parameters)
    {
    // i.e. Homepage::indexAction
    $controller = $parameters['_controller'];
    list($class, $method) = explode('::', $controller);
    $controller = new $class();
    return array($class, $method);
    }

    View full-size slide

  24. public function handle(Request $request /*,...*/)
    {
    $parameters = $this->matchRequest($request);
    $controller = $this->resolveController($parameters);
    $response = call_user_func($controller):
    return $response;
    }
    private function resolveController($parameters)
    {
    // i.e. Homepage::indexAction
    $controller = $parameters['_controller'];
    list($class, $method) = explode('::', $controller);
    $controller = new $class();
    return array($class, $method);
    }

    View full-size slide

  25. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
    use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
    public function __construct(
    RequestMatcherInterface $matcher,
    ControllerResolverInterface $resolver
    ) {
    $this->matcher = $matcher;
    $this->resolver = $resolver;
    }

    View full-size slide

  26. public function handle(Request $request /*,...*/)
    {
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller):
    return $response;
    }

    View full-size slide

  27. public function handle(Request $request /*,...*/)
    {
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller):
    return $response;
    }

    View full-size slide

  28. EventDispatcherInterface

    View full-size slide

  29. Handle
    Request
    Execute  a  
    controller  
    Geoip  lookup  
    Mobile  
    redirect  
    Authen6cate  
    ?  
    ?  
    Add    
    debug  to  
    response  
    ?  
    Match  a  
    request  

    View full-size slide

  30. Request Response
    Router Controller
    Resolver
    Event Dispatcher
    GeoipListener
    SessionListener
    LocaleListener
    Firewall
    kernel.request
    TemplateListener
    ControllerListener
    ParamConverter
    Listener
    TemplateListener

    View full-size slide

  31. Request Response
    Router Controller
    Resolver
    Event Dispatcher
    GeoipListener
    SessionListener
    LocaleListener
    Firewall
    kernel.request
    TemplateListener
    ControllerListener
    ParamConverter
    Listener
    TemplateListener

    View full-size slide

  32. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
    use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
    use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
    public function __construct(
    EventDispatcherInterface $dispatcher,
    RequestMatcherInterface $matcher,
    ControllerResolverInterface $resolver
    ) {
    $this->eventDispatcher = $dispatcher;
    $this->matcher = $matcher;
    $this->resolver = $resolver;
    }

    View full-size slide

  33. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller):
    return $response;
    }

    View full-size slide

  34. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller):
    return $response;
    }

    View full-size slide

  35. Request Response
    Router Controller
    Resolver
    Event Dispatcher
    GeoipListener
    SessionListener
    LocaleListener
    Firewall
    kernel.request

    View full-size slide

  36. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.request
    GeoipListener
    SessionListener
    LocaleListener
    RouterListener
    Firewall

    View full-size slide

  37. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
    use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
    public function __construct(
    EventDispatcherInterface $dispatcher,
    ControllerResolverInterface $resolver
    ) {
    $this->eventDispatcher = $dispatcher;
    $this->resolver = $resolver;
    }

    View full-size slide

  38. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller):
    return $response;
    }

    View full-size slide

  39. class RouterListener
    {
    public function __construct(
    RequestMatcherInterface $matcher
    ) {
    $this->matcher = $matcher
    }
    function onKernelRequest(GetResponseEvent $event)
    {
    // ...
    }
    }

    View full-size slide

  40. // RouterListener
    public function onKernelRequest(GetResponseEvent $event)
    {
    $request = $event->getRequest();
    if ($request->attributes->has('_controller')) {
    // routing is already done
    return;
    }
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    }

    View full-size slide

  41. // RouterListener
    public function onKernelRequest(GetResponseEvent $event)
    {
    $request = $event->getRequest();
    if ($request->attributes->has('_controller')) {
    // routing is already done
    return;
    }
    $parameters = $this->matcher->matchRequest($request);
    $request->attributes->add($parameters);
    }

    View full-size slide

  42. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.request
    GeoipListener
    SessionListener
    LocaleListener
    RouterListener
    Firewall

    View full-size slide

  43. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.request
    GeoipListener
    SessionListener
    LocaleListener
    RouterListener
    Firewall

    View full-size slide

  44. // RedirectListener
    public function onKernelRequest(GetResponseEvent $event)
    {
    $event->setResponse(
    new RedirectResponse('http://www.symfonyday.pt/')
    );
    }

    View full-size slide

  45. // HttpKernel
    public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    if ($event->hasResponse()) {
    return $event->getResponse();
    }
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller);
    return $response;
    }

    View full-size slide

  46. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.response
    CacheListener
    ResponseListener
    ProfilerListener WebDebugToolbar
    Listener

    View full-size slide

  47. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.finish_request
    LocaleListener RouterListener
    Firewall

    View full-size slide

  48. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.finish_request
    LocaleListener RouterListener
    Firewall

    View full-size slide

  49. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    if ($event->hasResponse()) {
    return $this->filterResponse($event->getResponse(), $request, $type);
    }
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller);
    return $this->filterResponse($response, $request, $type);
    }
    private function filterResponse(Response $response, Request $request, $type)
    {
    $event = new FilterResponseEvent(
    $this, $request, $type, $response
    );
    $this->dispatcher->dispatch('kernel.response', $event);
    $response = $event->getResponse();
    $event = new FinishRequestEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.finish_request', $event);
    return $response;
    }

    View full-size slide

  50. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    if ($event->hasResponse()) {
    return $this->filterResponse($event->getResponse(), $request, $type);
    }
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller);
    return $this->filterResponse($response, $request, $type);
    }
    private function filterResponse(Response $response, Request $request, $type)
    {
    $event = new FilterResponseEvent(
    $this, $request, $type, $response
    );
    $this->dispatcher->dispatch('kernel.response', $event);
    $response = $event->getResponse();
    $event = new FinishRequestEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.finish_request', $event);
    return $response;
    }

    View full-size slide

  51. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    if ($event->hasResponse()) {
    return $this->filterResponse($event->getResponse(), $request, $type);
    }
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller);
    return $this->filterResponse($response, $request, $type);
    }
    private function filterResponse(Response $response, Response $response, $type)
    {
    $event = new FilterResponseEvent(
    $this, $request, $type, $response
    );
    $this->dispatcher->dispatch('kernel.response', $event);
    $response = $event->getResponse();
    $event = new FinishRequestEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.finish_request', $event);
    return $response;
    }

    View full-size slide

  52. public function handle(Request $request, $type, $catch)
    {
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.request', $event);
    if ($event->hasResponse()) {
    return $this->filterResponse($event->getResponse(), $request, $type);
    }
    $controller = $this->resolver->resolve($request);
    $response = call_user_func($controller);
    return $this->filterResponse($response, $request, $type);
    }
    private function filterResponse(Response $response, Response $response, $type)
    {
    $event = new FilterResponseEvent(
    $this, $request, $type, $response
    );
    $this->dispatcher->dispatch('kernel.response', $event);
    $response = $event->getResponse();
    $event = new FinishRequestEvent($this, $request, $type);
    $this->dispatcher->dispatch('kernel.finish_request', $event);
    return $response;
    }

    View full-size slide

  53. Request Response
    Controller
    Resolver
    Event Dispatcher
    ControllerListener
    kernel.controller
    RequestDataCollector
    Listener
    ParamConverter
    Listener
    TemplateListener

    View full-size slide

  54. public function handle(Request $request, $type, $catch)
    {
    // ...
    $controller = $this->resolver->resolve($request);
    $event = new FilterControllerEvent(
    $this, $controller, $request, $type
    );
    $this->dispatcher->dispatch(
    'kernel.controller', $event
    );
    $controller = $event->getController();
    $response = call_user_func($controller);
    return $this->filterResponse($response, $request, $type);
    }

    View full-size slide

  55. public function handle(Request $request, $type, $catch)
    {
    // ...
    $controller = $this->resolver->resolve($request);
    $event = new FilterControllerEvent(
    $this, $controller, $request, $type
    );
    $this->dispatcher->dispatch(
    'kernel.controller', $event
    );
    $controller = $event->getController();
    $response = call_user_func($controller);
    return $this->filterResponse($response, $request, $type);
    }

    View full-size slide

  56. public function handle(Request $request, $type, $catch)
    {
    // ...
    $controller = $this->resolver->resolve($request);
    $event = new FilterControllerEvent(
    $this, $controller, $request, $type
    );
    $this->dispatcher->dispatch('kernel.controller', $event);
    $controller = $event->getController();
    $arguments = $this->resolver->getArguments(
    $request, $controller
    );
    $response = call_user_func($controller, $arguments);
    return $this->filterResponse($response, $request, $type);
    }

    View full-size slide

  57. Request Response
    Controller
    Resolver
    Event Dispatcher
    TemplateListener
    kernel.view

    View full-size slide

  58. public function handle(Request $request, $type, $catch)
    {
    // ...
    $response = call_user_func($controller, $arguments);
    if (!$response instance of Response) {
    $event = new GetResponseForControllerResultEvent(
    $this, $request, $type, $response
    );
    $this->dispatcher->dispatch(
    'kernel.view', $event
    );
    $response = $event->getResponse();
    }
    return $this->filterResponse($response, $request, $type);
    }

    View full-size slide

  59. public function handle(Request $request, $type, $catch)
    {
    // ...
    $response = call_user_func($controller, $arguments);
    if (!$response instance of Response) {
    $event = new GetResponseForControllerResultEvent(
    $this, $request, $type, $response
    );
    $this->dispatcher->dispatch(
    'kernel.view', $event
    );
    $response = $event->getResponse();
    }
    return $this->filterResponse($response, $request, $type);
    }

    View full-size slide

  60. Build-in events

    View full-size slide

  61. The usual path

    View full-size slide

  62. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.request
    FragmentListener
    SessionListener
    LocaleListener
    RouterListener
    Firewall

    View full-size slide

  63. Request Response
    Controller
    Resolver
    Event Dispatcher
    ControllerListener
    kernel.controller
    RequestDataCollector
    Listener
    ParamConverter
    Listener
    TemplateListener

    View full-size slide

  64. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.response
    CacheListener
    ResponseListener
    ProfilerListener
    WebDebugToolbar
    Listener

    View full-size slide

  65. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.finish_request
    LocaleListener RouterListener
    Firewall

    View full-size slide

  66. Request Response
    Controller
    Resolver
    Event Dispatcher
    TemplateListener
    kernel.view

    View full-size slide

  67. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.terminate
    ProfilerListener
    EmailSenderListener

    View full-size slide

  68. A Response set during
    kernel.request

    View full-size slide

  69. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.request
    FragmentListener
    SessionListener
    LocaleListener
    RouterListener
    Firewall

    View full-size slide

  70. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.response
    CacheListener
    ResponseListener
    ProfilerListener WebDebugToolbar
    Listener

    View full-size slide

  71. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.finish_request
    LocaleListener RouterListener
    Firewall

    View full-size slide

  72. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.finish_request
    LocaleListener RouterListener
    Firewall

    View full-size slide

  73. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.terminate
    TraceableEvent
    Dispatcher ProfilerListener
    EmailSenderListener

    View full-size slide

  74. An exception thrown during
    handling a request

    View full-size slide

  75. Request Response
    Controller
    Resolver
    Event Dispatcher
    kernel.request
    FragmentListener
    SessionListener
    LocaleListener
    RouterListener
    Firewall

    View full-size slide

  76. Request Response
    Controller
    Resolver
    Event Dispatcher
    ExceptionListener
    AccessDeniedListener
    ProfilerListener
    kernel.exception

    View full-size slide

  77. Symfony\Component\HttpKernel\HttpKernel
    Read more...

    View full-size slide

  78. KernelInterface

    View full-size slide

  79. interface KernelInterface
    extends HttpKernelInterface, \Serializable
    {
    public function registerBundles();
    public function registerContainerConfiguration(
    LoaderInterface $loader);
    public function boot();
    public function shutdown();
    public function getBundles();
    public function isClassInActiveBundle($class);
    public function getBundle($name, $first = true);
    public function locateResource($name, $dir = null, $first = true);
    public function getName();
    public function getEnvironment();
    public function isDebug();
    public function getRootDir();
    public function getContainer();
    public function getStartTime();
    public function getCacheDir();
    public function getLogDir();
    public function getCharset();
    }

    View full-size slide

  80. HKernel  
    App  Kernel  
    Request Response

    View full-size slide

  81. HKernel  
    App  Kernel  
    Request Response
    App  Cache  

    View full-size slide

  82. class Kernel implements KernelInterface
    {
    public function handle(
    Request $request,
    $type = HttpKernelInterface::MASTER_REQUEST,
    $catch = true)
    ) {
    if (false === $this->booted) {
    $this->boot();
    }
    return $this->container->get('http_kernel')
    ->handle($request, $type, $catch);
    }
    }

    View full-size slide

  83. class Kernel implements KernelInterface
    {
    public function handle(
    Request $request,
    $type = HttpKernelInterface::MASTER_REQUEST,
    $catch = true)
    ) {
    if (false === $this->booted) {
    $this->boot();
    }
    return $this->container->get('http_kernel')
    ->handle($request, $type, $catch);
    }
    }

    View full-size slide

  84. class Kernel implements KernelInterface
    {
    public function handle(
    Request $request,
    $type = HttpKernelInterface::MASTER_REQUEST,
    $catch = true)
    ) {
    if (false === $this->booted) {
    $this->boot();
    }
    return $this->container->get('http_kernel')
    ->handle($request, $type, $catch);
    }
    }

    View full-size slide

  85. public function boot()
    {
    $this->initializeBundles();
    $this->initializeContainer();
    foreach ($this->getBundles() as $bundle) {
    $bundle->setContainer($this->container);
    $bundle->boot();
    }
    $this->booted = true;
    }

    View full-size slide

  86. protected function initializeContainer()
    {
    // ...
    if (!$cache->isFresh()) {
    $container = $this->buildContainer();
    $container->compile();
    $this->dumpContainer($cache, $container/*…*/);
    }
    require_once $cache;
    $this->container = new $class();
    $this->container->set('kernel', $this);
    // ...
    }

    View full-size slide

  87. protected function initializeContainer()
    {
    // ...
    if (!$cache->isFresh()) {
    $container = $this->buildContainer();
    $container->compile();
    $this->dumpContainer($cache, $container/*…*/);
    }
    require_once $cache;
    $this->container = new $class();
    $this->container->set('kernel', $this);
    // ...
    }

    View full-size slide

  88. class appDevDebugProjectContainer extends Container
    {
    // ...
    protected function getLoggerService()
    {
    $this->services['logger'] = $instance
    = new \Symfony\Bridge\Monolog\Logger('app');
    $instance->pushHandler($this->get('monolog.handler.console'));
    $instance->pushHandler($this->get('monolog.handler.main'));
    $instance->pushHandler($this->get('monolog.handler.debug'));
    return $instance;
    }
    // ...
    }

    View full-size slide

  89. protected function initializeContainer()
    {
    // ...
    if (!$cache->isFresh()) {
    $container = $this->buildContainer();
    $container->compile();
    $this->dumpContainer($cache, $container/*…*/);
    }
    require_once $cache;
    $this->container = new $class();
    $this->container->set('kernel', $this);
    // ...
    }

    View full-size slide

  90. protected function initializeContainer()
    {
    // ...
    if (!$cache->isFresh()) {
    $container = $this->buildContainer();
    $container->compile();
    $this->dumpContainer($cache, $container/*…*/);
    }
    require_once $cache;
    $this->container = new $class();
    $this->container->set('kernel', $this);
    // ...
    }

    View full-size slide

  91. Container and events
    in a legacy application

    View full-size slide

  92. $kernel = new \AppKernel('dev', true);
    $kernel->boot();
    $request = Request::createFromGlobals();
    $request->attributes->set('is_legacy', true);
    $container = $kernel->getContainer();
    $container->enterScope('request');
    $container->get('request_stack')->push($request);
    $event = new GetResponseEvent(
    $kernel,
    $request,
    HttpKernelInterface::MASTER_REQUEST
    );
    $container->get('event_dispatcher');
    ->dispatch('kernel.request', $event);

    View full-size slide

  93. $kernel = new \AppKernel('dev', true);
    $kernel->boot();
    $request = Request::createFromGlobals();
    $request->attributes->set('is_legacy', true);
    $container = $kernel->getContainer();
    $container->enterScope('request');
    $container->get('request_stack')->push($request);
    $event = new GetResponseEvent(
    $kernel,
    $request,
    HttpKernelInterface::MASTER_REQUEST
    );
    $container->get('event_dispatcher');
    ->dispatch('kernel.request', $event);

    View full-size slide

  94. $kernel = new \AppKernel('dev', true);
    $kernel->boot();
    $request = Request::createFromGlobals();
    $request->attributes->set('is_legacy', true);
    $container = $kernel->getContainer();
    $container->enterScope('request');
    $container->get('request_stack')->push($request);
    $event = new GetResponseEvent(
    $kernel,
    $request,
    HttpKernelInterface::MASTER_REQUEST
    );
    $container->get('event_dispatcher');
    ->dispatch('kernel.request', $event);

    View full-size slide

  95. $kernel = new \AppKernel('dev', true);
    $kernel->boot();
    $request = Request::createFromGlobals();
    $request->attributes->set('is_legacy', true);
    $container = $kernel->getContainer();
    $container->enterScope('request');
    $container->get('request_stack')->push($request);
    $event = new GetResponseEvent(
    $kernel,
    $request,
    HttpKernelInterface::MASTER_REQUEST
    );
    $container->get('event_dispatcher');
    ->dispatch('kernel.request', $event);

    View full-size slide

  96. $kernel = new \AppKernel('dev', true);
    $kernel->boot();
    $request = Request::createFromGlobals();
    $request->attributes->set('is_legacy', true);
    $container = $kernel->getContainer();
    $container->enterScope('request');
    $container->get('request_stack')->push($request);
    $event = new GetResponseEvent(
    $kernel,
    $request,
    HttpKernelInterface::MASTER_REQUEST
    );
    $container->get('event_dispatcher');
    ->dispatch('kernel.request', $event);

    View full-size slide

  97. class RouterListener extends BaseRouterListener
    {
    public function onKernelRequest(
    GetResponseEvent $event
    ) {
    $request = $event->getRequest();
    try {
    parent::onKernelRequest($event);
    } catch (NotFoundHttpException $e) {
    if (!$request->attributes->get('is_legacy')) {
    throw $e;
    }
    }
    }
    }

    View full-size slide

  98. Thank you!
    https://joind.in/10782

    View full-size slide