DeSymfony 2012: Symfony internals

2,903 views
2,835 views

Published on

Slides de la charla 'Symfony Internals' en DeSymfony 2012

Published in: Technology
1 Comment
5 Likes
Statistics
Notes
No Downloads
Views
Total views
2,903
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
80
Comments
1
Likes
5
Embeds 0
No embeds

No notes for slide

DeSymfony 2012: Symfony internals

  1. 1. ¿Quién soy? Raúl Fraile @raulfrailePHP/Symfony2 freelance developer
  2. 2. ¿Qué hago?
  3. 3. SensioLabsConnect
  4. 4. ¿Por qué?
  5. 5. app[_dev].phpControlador frontal
  6. 6. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send();
  7. 7. bootstrap.php.cacheClases/namespaces en un único fichero.
  8. 8. bootstrap.php.cache// app/bootstrap.php.cachenamespace { require_once __DIR__./autoload.php; }namespace SymfonyComponentDependencyInjection{ interface ContainerAwareInterface { function setContainer(ContainerInterface $container = null); } ...}
  9. 9. bootstrap.php.cacheReduce operaciones I/O
  10. 10. bootstrap.php.cacheCarga autoload.php
  11. 11. autoload.php// app/autoload.phpuse SymfonyComponentClassLoaderUniversalClassLoader;$loader = new UniversalClassLoader();$loader->registerNamespaces(array( Symfony => array( __DIR__./../vendor/symfony/src, __DIR__./../vendor/bundles), Assetic => __DIR__./../vendor/assetic/src,));$loader->registerPrefixes(array( Twig_ => __DIR__./../vendor/twig/lib,));
  12. 12. ClassLoader Autoload declases/interfaces en Symfony2
  13. 13. ClassLoader
  14. 14. ClassLoaderImplementa PSR-0
  15. 15. PSR-0Aprobado por el “Framework Interop Group”github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
  16. 16. PSR-0Fully Qualified Name SymfonyCoreRequest ZendMailMessage [vendor_path]/Symfony/Core/Request.php [vendor_path]/Zend/Mail/Message.php Filesystem
  17. 17. ClassLoader// namespaced class name$namespace = substr($class, 0, $pos);foreach ($this->namespaces as $ns => $dirs) { if (0 !== strpos($namespace, $ns)) { continue; } foreach ($dirs as $dir) { $className = substr($class, $pos + 1); $file = $dir . DIR_SEPARATOR . str_replace(,DIR_SEPARATOR, $namespace) . DIR_SEPARATOR . str_replace(_, DIR_SEPARATOR, $className) . .php; if (file_exists($file)) { return $file; } }}
  18. 18. ClassLoader $loader->findFile( SymfonyComponentHttpFoundationRequest );/Sites/desymfony/app/../vendor/symfony/src/ Symfony/Component/HttpFoundation/Request.php
  19. 19. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send();
  20. 20. AppKernel.php// src/AppKernel.phpuse SymfonyComponentHttpKernelKernel;use SymfonyComponentConfigLoaderLoaderInterface;class AppKernel extends Kernel{ public function registerBundles() { $bundles = array( new SymfonyBundleTwigBundleTwigBundle(), ... ); return $bundles; } public function registerContainerConfiguration(LoaderInterface $loader) { $loader->load(__DIR__./config/config_.$this->getEnvironment()..yml); }}
  21. 21. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send(); Debug Environment
  22. 22. AppKernel.phpIf (true === $debug) { Guarda inicio petición (microtime) display_errors = 1 error_reporting = -1 DebugUniversalClassLoader} else { display_errors = 0}
  23. 23. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send();
  24. 24. LoadClassCacheObjetivo: mapear FQN ypaths de las principales clases/interfaces
  25. 25. LoadClassCache Se cachea en classes.map yclasses.php.meta
  26. 26. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send();
  27. 27. Request ComponenteHttpFoundation
  28. 28. RequestAbstracción OO deuna petición HTTP
  29. 29. Request RequestGET /index.php HTTP/1.1␍␊Host: test.com␍␊ $_GET queryAccept-Language:en;q=0.8␍␊ requestAccept-Encoding:gzip␍␊ $_POST cookiesUser-Agent: Mozilla/5.0␍␊␍␊ files $_COOKIE server headers $_FILES getHost $_SERVER getClientIp ...
  30. 30. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send();
  31. 31. HttpKernelCorazón de Symfony
  32. 32. HttpKernel Gestiona entornoformado por bundles, DIC...
  33. 33. $kernel->boot()Inicialización de bundles y DIC
  34. 34. $kernel->initializeBundles() Se cargan los bundles definidos enAppKernel::registerBundles()
  35. 35. $kernel->initializeContainer() Se genera usando el ContainerBuilder del DependencyInjection
  36. 36. ContainerBuilder// example.com/src/container.phpuse SymfonyComponentDependencyInjection;use SymfonyComponentDependencyInjectionReference;$sc = new DependencyInjectionContainerBuilder();$sc->register(context, SymfonyComponentRoutingRequestContext);$sc->register(matcher, SymfonyComponentRoutingMatcherUrlMatcher) ->setArguments(array($routes, new Reference(context)));$sc->register(framework, SimplexFramework) ->setArguments(array(new Reference(dispatcher), newReference(resolver))) ; http://fabien.potencier.org/article/62/create-your-own-framework-on-top-of-the-symfony2-components-part-12
  37. 37. $kernel->initializeContainer() {rootDir}{Environment} [Debug]ProjectContainer
  38. 38. $kernel->initializeContainer()Por cada bundle se ejecuta Bundle::build() y seregistran sus extensiones
  39. 39. $kernel->boot()Por cada bundle se asignael container y se ejecuta el boot()
  40. 40. $kernel->handle()Objetivo: Devolver un objeto Response
  41. 41. Evento kernel.requestSe lanza en cuanto llega la petición
  42. 42. Evento kernel.request Un listener puededevolver un Responsey finalizar la ejecución
  43. 43. Evento kernel.requestFrameworkBundle loutiliza para rellenar el valor de _controller
  44. 44. RouterListenerUtiliza un RouterMatcher(autogenerado por comp. Routing)
  45. 45. RouterListener// app/cache/dev/appdevUrlMatcher.phpclass appdevUrlMatcher extends RedirectableUrlMatcher{ ... public function match($pathinfo) { ... // _demo_hello if (0 === strpos($pathinfo, /demo/hello) && preg_match(#^/demo/hello/(?P<name>[^/]+?)$#s, $pathinfo, $m)) { return array_merge($this->mergeDefaults($m, array( _controller => AcmeDemoBundleControllerDemoController::helloAction) ), array( _route => _demo_hello)); } ... }
  46. 46. ControllerResolverEncargado de devolver uncontrolador + argumentos a partir de _controller
  47. 47. FrameworkBundleAgrupa componentes ylibrerías para crear un framework MVC
  48. 48. FrameworkBundleAdemás, ofrece...
  49. 49. FrameworkBundlephp app/console
  50. 50. FrameworkBundle// app/console#!/usr/bin/env php<?phprequire_once __DIR__./bootstrap.php.cache;require_once __DIR__./AppKernel.php;use SymfonyBundleFrameworkBundleConsoleApplication;use SymfonyComponentConsoleInputArgvInput;$input = new ArgvInput();$env = $input->getParameterOption(array(--env, -e), getenv(SYMFONY_ENV) ?: dev);$debug = !$input->hasParameterOption(array(--no-debug, ));$kernel = new AppKernel($env, $debug);$application = new Application($kernel);$application->run();
  51. 51. FrameworkBundleComandos assets:install cache:clear cache:warmup container:debugrouter:dump-apache router:debug
  52. 52. FrameworkBundleController
  53. 53. FrameworkBundle// src/Acme/DemoBundle/Controller/DemoControllernamespace AcmeDemoBundleController;use SymfonyBundleFrameworkBundleControllerController;class DemoController extends Controller{ public function helloAction($name) { ... }}
  54. 54. FrameworkBundleY mucho más: ESI, WebTestCase,DataCollectors...
  55. 55. Evento kernel.controller Una vez definido elcontrolador, se lanza el evento
  56. 56. Evento kernel.controller Se puede cambiar,pasando un Callable
  57. 57. Evento kernel.viewSe lanza si el Controllerno devuelve un objeto Response
  58. 58. Evento kernel.viewObjetivo: construir unobjeto Response delreturn del Controller
  59. 59. Evento kernel.responsePermite reemplazar o modificar el objeto Response
  60. 60. Evento kernel.exception Oportunidad paraconvertir una Exception en un Response
  61. 61. Eventos Todos heredan de KernelEventgetRequestType(): MASTER_REQUEST o SUB_REQUESTgetKernel();getRequest();
  62. 62. ResponseResponse HTTP/1.1 200 OK Headers Content-type: text/html Date:Thu, 31 May 2012 17:54:50 GMT Version Content <!DOCTYPE HTML> <html lang="es"> <head>Status code <meta charset="utf-8"> ...Status text Charset
  63. 63. app[_dev].php// web/app[_env].php1. require_once __DIR__./../app/bootstrap.php.cache;2. require_once __DIR__./../app/AppKernel.php;3. use SymfonyComponentHttpFoundationRequest;4. $kernel = new AppKernel(dev, true);5. $kernel->loadClassCache();6. $kernel->handle(Request::createFromGlobals())->send();
  64. 64. Response::send()Envía las cabeceras y el contenido
  65. 65. Response::send()
  66. 66. Demohttps://github.com/raulfraile/ internals-desymfony2012
  67. 67. ¡Gracias!
  68. 68. Fotografíashttp://www.flickr.com/photos/connectirmeli/7233514862 http://www.flickr.com/photos/barretthall/6070677596http://www.flickr.com/photos/f-oxymoron/5005673112/
  69. 69. ¿Preguntas?

×