Symfony2 - WebExpo 2010
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
4,514
On Slideshare
3,515
From Embeds
999
Number of Embeds
10

Actions

Shares
Downloads
58
Comments
2
Likes
3

Embeds 999

http://ontwik.com 799
http://webexpo.cz 106
http://coderwall.com 66
http://webexpo.net 22
http://webcache.googleusercontent.com 1
http://translate.googleusercontent.com 1
http://localhost:3000 1
http://localhost 1
http://www.linkedin.com 1
http://www.alkowebizer.sk 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Symfony2 Fabien Potencier
  • 2. How many of you have already used symfony1?
  • 3. How many of you have already played with Symfony2?
  • 4. What is Symfony2?
  • 5. A set of decoupled and cohesive components
  • 6. DependencyInjection EventDispatcher HttpFoundation OutputEscaper DomCrawler CssSelector Templating HttpKernel BrowserKit Validator Routing Console Process Finder Form Yaml
  • 7. git clone git://github.com/symfony/symfony.git
  • 8. A set of decoupled and cohesive components Autoloading
  • 9. PEAR_Log > PEAR/Log.php Zend_Log > Zend/Log.php Swift_Mime_Message > Swift/Mime/Message.php Twig_Node_For > Twig/Node/For.php
  • 10. SymfonyFoundationKernel Symfony/Foundation/Kernel.php DoctrineDBALDriver Doctrine/DBAL/Driver.php pdependreflectionReflectionSession pdepend/reflection/ReflectionSession.php http://groups.google.com/group/php-standards/web/psr-0-final-proposal  
  • 11. require_once '.../Symfony/Framework/ UniversalClassLoader.php'; use SymfonyFrameworkUniversalClassLoader; $loader = new UniversalClassLoader(); $loader->register();
  • 12. $loader->registerNamespaces(array( 'Symfony' => '/path/to/symfony/src', 'Doctrine' => '/path/to/doctrine/lib', 'pdepend' => '/path/to/reflection/source', )); PHP 5.3 technical interoperability standards
  • 13. $loader->registerPrefixes(array( 'Swift_' => '/path/to/swiftmailer/lib/classes', 'Zend_' => '/path/to/vendor/zend/library', )); PEAR style
  • 14. A set of decoupled and cohesive components Process
  • 15. use SymfonyComponentProcessProcess; $cmd = 'ssh 1.2.3.4 "ps waux"'; $process = new Process($cmd); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException( $process->getErrorOutput()); } echo $process->getOutput();
  • 16. $cmd = 'ssh 1.2.3.4 "tail -f /some/log"'; $process = new Process($cmd); $process->run(function ($type, $buffer) { echo $buffer; });
  • 17. use SymfonyComponentProcessPhpProcess; $process = new PhpProcess( '<?php echo "hello"; ?>'); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException( $process->getErrorOutput()); } echo $process->getOutput();
  • 18. A set of decoupled and cohesive components CssSelector
  • 19. use SymfonyComponentCssSelectorParser; Parser::cssToXpath('h4 > a:contains("foo")');
  • 20. use SymfonyComponentCssSelectorParser; $document = new DOMDocument(); $document->loadHTMLFile('...'); $xpath = new DOMXPath($document); $expr = Parser::cssToXpath('a.smart'); $nodes = $xpath->query($expr); foreach ($nodes as $node) { printf("%s (%s)n", $node->nodeValue, $node- >getAttribute('href')); }
  • 21. A set of decoupled and cohesive components Finder
  • 22. use SymfonyComponentFinderFinder; $finder = new Finder(); $finder ->files() ->in(__DIR__) ->...() ->sortByName() ;
  • 23. $finder ->name('*.php') ->depth('<= 1') ->date('>= yesterday') ->size('<= 1K') ->filter(function (SplFileInfo $file) { return strlen($file->getBasename()) < 9; }) ;
  • 24. foreach ($finder as $file) { print $file->getRealpath()."n"; } $files = iterator_to_array($finder); $count = iterator_count($finder);
  • 25. use SymfonyComponentFinderFinder; $s3 = new Zend_Service_Amazon_S3($key, $sct); $s3->registerStreamWrapper("s3"); $finder = new Finder(); $finder ->name('photos*') ->size('< 100K') ->date('since 1 hour ago') ->in('s3://bucket-name') ;
  • 26. A set of decoupled and cohesive components Routing
  • 27. /blog.php?section=symfony&article_id=18475
  • 28. web/ index.php
  • 29. /index.php/blog/2010/09/18/Symfony2-in-India
  • 30. /blog/2010/09/18/Symfony2-in-India
  • 31. /blog/:year/:month/:day/:slug
  • 32. post: pattern: /blog/:year/:month/:day/:slug defaults: { _controller: BlogBundle:Post:show }
  • 33. <routes> <route id="post" pattern="/blog/:year/:month/:day/:slug"> <default key="_controller"> BlogBundle:Post:show </default> </route> </routes>
  • 34. use SymfonyComponentRoutingRouteCollection; use SymfonyComponentRoutingRoute; $collection = new RouteCollection(); $route = new Route( '/blog/:year/:month/:day/:slug', array('_controller' => 'BlogBundle:Post:show')); $collection->addRoute('post', $route); return $collection;
  • 35. $router ->match('/blog/2010/09/18/Symfony2-in-India') $router ->generate('post', array('slug' => '...'))
  • 36. post: pattern: /post/:slug defaults: { _controller: BlogBundle:Post:show }
  • 37. $router ->generate('post', array('slug' => '...'))
  • 38. An Object-Oriented abstraction on top of PHP
  • 39. An Object-Oriented abstraction on top of PHP Request
  • 40. use SymfonyComponentHttpFoundationRequest; $request = new Request(); // get a $_GET parameter $request->query->get('page'); // get a $_POST parameter $request->request->get('page'); // get a $_COOKIE parameter $request->cookies->get('name'); $request->getPreferredLanguage(array('en', 'fr')); $request->isXmlHttpRequest();
  • 41. // get a $_FILE parameter $f = $request->files->get('image'); // $f is an instance of // SymfonyComponentHttpFoundationFileUploadedFile // guess extension, based on the mime type $n = '/path/to/file'.$file->getDefaultExtension(); $f->move($n);
  • 42. new Request(); new Request( $_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER ); Request::create('/hello/Fabien', 'GET');
  • 43. An Object-Oriented abstraction on top of PHP Session
  • 44. $session = $request->getSession(); $session->set('foo', 'bar'); $session->get('foo'); $session->setFlash('notice', 'Congratulations!');
  • 45. An Object-Oriented abstraction on top of PHP Response
  • 46. use SymfonyComponentHttpFoundationResponse; $response = new Response('Hello World', 200, array('Content-Type' => 'text/plain')); $response->send(); $response->setHeader('Content-Type', 'text/ plain'); $response->setCookie('foo', 'bar'); $response->setContent('Hello World'); $response->setStatusCode(200);
  • 47. An Object-Oriented abstraction of the HTTP dialog
  • 48. A MVC Web Framework
  • 49. The Symfony2 MVC Philosophy
  • 50. Be as easy as possible for newcomers and as flexible as possible for advanced users
  • 51. MVC
  • 52. http://symfony-reloaded.org/ http://symfony-reloaded.org/downloads/ sandbox_2_0_PR3.zip
  • 53. post: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index } namespace ApplicationHelloBundleController; use SymfonyBundleFrameworkBundleController; class HelloController extends Controller { public function indexAction($name) { return new Response('Hello '.$name); } }
  • 54. namespace ApplicationHelloBundleController; use SymfonyBundleFrameworkBundleController; class HelloController extends Controller { public function indexAction($name) { // Get things from the Model return $this->render( 'HelloBundle:Hello:index', array('name' => $name) ); } }
  • 55. Hello <?php echo $name ?>!
  • 56. <?php $view->extend('HelloBundle::layout') ?> Hello <?php echo $name ?>!
  • 57. <html> <head> <title> <?php $view['slots']->output('title') ?> </title> </head> <body> <?php $view['slots']->output('_content') ?> </body> </html>
  • 58. slot title Lorem  ipsum  dolor  sit  amet,  consectetur  adipiscing  elit.  In  vel   _content Lorem  ipsum  dolor  sit  amet,  consectetur  adipiscing  elit.  In  vel  nulla  arcu,   vitae  cursus  nunc.  Integer  semper  turpis  et  enim  por6tor  iaculis.  Nulla   facilisi.  Lorem  ipsum  dolor  sit  amet,  consectetur  adipiscing  elit.  Mauris   vehicula  ves;bulum  dictum.  Aenean  non  velit  tortor.  Nullam  adipiscing   malesuada  aliquam.  Mauris  dignissim,  urna  quis  iaculis  tempus,  justo   layout libero  por6tor  est,  nec  eleifend  est  elit  vitae  ante.  Curabitur  interdum   luctus  metus,  in  pulvinar  lectus  rutrum  sit  amet.  Duis  gravida,  metus  in   dictum  eleifend,  dolor  risus  ;ncidunt  ligula,  non  volutpat  nulla  sapien  in   elit.  Nulla  rutrum  erat  id  neque  suscipit  eu  ultricies  odio  sollicitudin.   Aliquam  a  mi  vel  eros  placerat  hendrerit.  Phasellus  por6tor,  augue  sit   amet  vulputate  venena;s,  dui  leo  commodo  odio,  a  euismod  turpis   ligula  in  elit.     slot
  • 59. {% extends "HelloBundle::layout" %} {% block content %} Hello {{ name }}! {% endblock %}
  • 60. <html> <head> <title> {% block title %}{% endblock %} </title> </head> <body> {% block body %}{% endblock %} </body> </html>
  • 61. ~ PAC / HMVC http://en.wikipedia.org/wiki/Presentation-abstraction-control
  • 62. Lorem  ipsum  dolor  sit  amet,  consectetur   Lorem  ipsum  dolor  sit   layout adipiscing  elit.  In  vel  nulla  arcu,  vitae   amet,  consectetur   cursus  nunc.  Integer  semper  turpis  et  enim   adipiscing  elit.  In  vel  nulla   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   arcu,  vitae  cursus  nunc.   dolor  sit  amet,  consectetur  adipiscing  elit.   Integer  semper  turpis  et   Mauris  vehicula  ves;bulum  dictum.   enim  por6tor  iaculis.   Aenean  non  velit  tortor.  Nullam  adipiscing   Nulla  facilisi.  Lorem  ipsum   malesuada  aliquam.  Mauris  dignissim,  urna   dolor  sit  amet,   quis  iaculis  tempus,  justo  libero  por6tor   consectetur  adipiscing  elit.   est,  nec  eleifend  est  elit  vitae  ante.   Mauris  vehicula   Curabitur  interdum  luctus  metus,  in   ves;bulum  dictum.   pulvinar  lectus  rutrum  sit  amet.  Duis   Aenean  non  velit  tortor.   gravida,  metus  in  dictum  eleifend,  dolor   Nullam  adipiscing   risus  ;ncidunt  ligula,  non  volutpat  nulla   malesuada  aliquam.   sapien  imain controller n  elit.  Nulla  rutrum  erat  id  neque   embedded MVC Mauris  dignissim,  urna   suscipit  eu  ultricies  odio  sollicitudin.   (_content slot) quis  iaculis  tempus,  justo   controller Aliquam  a  mi  vel  eros  placerat  hendrerit.   libero  por6tor  est,  nec   Phasellus  por6tor,  augue  sit  amet   eleifend  est  elit  vitae  ante.   vulputate  venena;s,  dui  leo  commodo   Curabitur  interdum  luctus   odio,  a  euismod  turpis  ligula  in  elit.     metus.  
  • 63. public function indexAction($name) { $embedded = $this['controller_resolver'] ->render('HelloBundle:Hello:foo', array('name' => $name)); return $this->render( 'HelloBundle:Hello:index', array( 'name' => $name, 'embedded' => $embedded, ) ); }
  • 64. <?php $view->extend('...:layout') ?> Lorem ipsum... <?php echo $view['actions'] ->render('HelloBundle:Hello:foo', array('name' => $name)) ?> Lorem ipsum...
  • 65. Bundles
  • 66. .../ SomeBundle/ Controller/ Entity/ Resources/ config/ views/ SomeBundle.php Tests/
  • 67. public function registerBundleDirs() { return array( 'Application' => __DIR__.'/../src/Application', 'Bundle' => __DIR__.'/../src/Bundle', 'SymfonyBundle' => __DIR__.'/../src/vendor/ symfony/src/Symfony/Bundle', ); }
  • 68. $this->render('SomeBundle:Hello:index', $params)
  • 69. hello: pattern: /hello/:name defaults: { _controller: SomeBundle:Hello:index }
  • 70. SomeBundle can be any of ApplicationSomeBundle BundleSomeBundle SymfonyBundleSomeBundle
  • 71. Environments
  • 72. Developers Customer End Users Development Staging Production Environment Environment Environment
  • 73. cache cache cache debug   debug   debug   logs   logs   logs   stats stats stats Development Staging Production Environment Environment Environment
  • 74. # config/config.yml doctrine.dbal: dbname: mydbname user: root password: %doctrine.dbal_password% swift.mailer: transport: smtp host: localhost
  • 75. # config/config_dev.yml imports: - { resource: config.yml } doctrine.dbal: password: null swift.mailer: transport: gmail username: xxxxxxxx password: xxxxxxxx
  • 76. # Doctrine Configuration doctrine.dbal: dbname: xxxxxxxx user: xxxxxxxx password: ~ # Swiftmailer Configuration swift.mailer: transport: smtp encryption: ssl auth_mode: login host: smtp.gmail.com username: xxxxxxxx password: xxxxxxxx
  • 77. <!-- Doctrine Configuration --> <doctrine:dbal dbname="xxxxxxxx" user="xxxxxxxx" password="" /> <!-- Swiftmailer Configuration --> <swift:mailer transport="smtp" encryption="ssl" auth_mode="login" host="smtp.gmail.com" username="xxxxxxxx" password="xxxxxxxx" />
  • 78. // Doctrine Configuration $container->loadFromExtension('doctrine', 'dbal', array( 'dbname' => 'xxxxxxxx', 'user' => 'xxxxxxxx', 'password' => '', )); // Swiftmailer Configuration $container->loadFromExtension('swift', 'mailer', array( 'transport' => "smtp", 'encryption' => "ssl", 'auth_mode' => "login", 'host' => "smtp.gmail.com", 'username' => "xxxxxxxx", 'password' => "xxxxxxxx", ));
  • 79. Dependency Injection Container
  • 80. Third-party libraries integration Unified Configuration
  • 81. # Twig Configuration twig.config: auto_reload: true # Zend Logger Configuration zend.logger: priority: debug path: %kernel.root_dir%/logs/ %kernel.environment%.log
  • 82. Configuration formats XML, YAML, PHP, INI, or Annotations Parameters management Fast (cached) Inheritance Sensitive data security …
  • 83. <doctrine:dbal dbname="sfweb" username="root" password="SuperSecretPasswordThatAnyoneCanSee" />
  • 84. in a .htaccess or httpd.conf file SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar" %doctrine.dbal.password%
  • 85. <doctrine:dbal dbname="sfweb" username="root" password="%doctrine.dbal.password%" />
  • 86. Developer Tools
  • 87. INFO: Matched route "blog_home" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'index', '_route' => 'blog_home',)) INFO: Using controller "BundleBlogBundleController PostController::indexAction" INFO: SELECT s0_.id AS id0, s0_.title AS title1, s0_.html_body AS html_body2, s0_.excerpt AS excerpt3, s0_.published_at AS published_at4 FROM sf_weblog_post s0_ ORDER BY s0_.published_at DESC LIMIT 10 (array ())
  • 88. INFO: Matched route "blog_post" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'show', '_format' => 'html', 'id' => '3456', '_route' => 'blog_post',)) INFO: Using controller "BundleBlogBundleController PostController::showAction » INFO: SELECT s0_.id AS id0, s0_.title AS title1, s0_.html_body AS html_body2, s0_.excerpt AS excerpt3, s0_.published_at AS published_at4 FROM sf_weblog_post s0_ WHERE s0_.id = ? (array ( 0 => '3456',)) ERR: Post "3456" not found! (No result was found for query although at least one row was expected.) (uncaught SymfonyComponentsRequestHandlerException NotFoundHttpException exception) INFO: Using controller "SymfonyFrameworkWebBundleController ExceptionController::exceptionAction"
  • 89. DEBUG: Notifying (until) event "core.request" to listener "(SymfonyFrameworkWebBundleListenerRequestParser, resolve)" INFO: Matched route "blog_post" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'show', '_format' => 'html', 'id' => '3456', '_route' => 'blog_post',)) DEBUG: Notifying (until) event "core.load_controller" to listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" INFO: Using controller "BundleBlogBundleControllerPostController::showAction" DEBUG: Listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" processed the event "core.load_controller" INFO: Trying to get post "3456" from database INFO: SELECT s0_.id AS id0, s0_.title AS title1, s0_.html_body AS html_body2, s0_.excerpt AS excerpt3, s0_.published_at AS published_at4 FROM sf_weblog_post s0_ WHERE s0_.id = ? (array ( 0 => '3456',)) DEBUG: Notifying (until) event "core.exception" to listener "(SymfonyFrameworkWebBundleListenerExceptionHandler, handle)" ERR: Post "3456" not found! (No result was found for query although at least one row was expected.) (uncaught SymfonyComponents RequestHandlerExceptionNotFoundHttpException exception) DEBUG: Notifying (until) event "core.request" to listener "(SymfonyFrameworkWebBundleListenerRequestParser, resolve)" DEBUG: Notifying (until) event "core.load_controller" to listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" INFO: Using controller "SymfonyFrameworkWebBundleControllerExceptionController::exceptionAction" DEBUG: Listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" processed the event "core.load_controller" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleListenerResponseFilter, filter)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugDataCollector DataCollectorManager, handle)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugWebDebugToolbar, handle)" DEBUG: Listener "(SymfonyFrameworkWebBundleListenerExceptionHandler, handle)" processed the event "core.exception" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleListenerResponseFilter, filter)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugDataCollector DataCollectorManager, handle)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugWebDebugToolbar, handle)"
  • 90. Security XSS / CSRF / SQL Injection
  • 91. Functional Tests
  • 92. $client = $this->createClient(); $crawler = $client->request( 'GET', '/hello/Fabien'); $this->assertTrue($crawler->filter( 'html:contains("Hello Fabien")')->count());
  • 93. $this->assertEquals( 10, $crawler->filter('div.hentry')->count()); $this->assertTrue( $client->getResponse()->isSuccessful());
  • 94. $crawler = $client->request( 'GET', 'hello/Lucas' );
  • 95. $link = $crawler->selectLink("Greet Lucas"); $client->click($link);
  • 96. $form = $crawler->selectButton('submit'); $client->submit($form, array( 'name' => 'Lucas', 'country' => 'France', 'like_symfony' => true, 'photo' => '/path/to/lucas.jpg', ));
  • 97. $harry = $this->createClient(); $sally = $this->createClient(); $harry->request('POST', '/say/sally/Hello'); $sally->request('GET', '/messages'); $this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this->assertRegExp('/Hello/', $sally->getResponse()->getContent());
  • 98. $harry = $this->createClient(); $sally = $this->createClient(); $harry->insulate(); $sally->insulate(); $harry->request('POST', '/say/sally/Hello'); $sally->request('GET', '/messages'); $this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this->assertRegExp('/Hello/', $sally->getResponse()->getContent());
  • 99. Caching
  • 100. HTTP Expiration / HTTP Validation
  • 101. $response->setSharedMaxAge(...); $response->setTtl(...); $response->setMaxAge(...); $response->setClientTtl(...); $response->setExpires(...); $response->setETag(...); $response->setLastModified(...);
  • 102. Cache-Control: s-maxage=10
  • 103. public function showAction() { // ... $response = $this->render('...', $vars); $response->setSharedMaxAge(10); return $response; }
  • 104. Symfony 2 comes built-in with an HTTP accelerator
  • 105. cacheable for 10 seconds cacheable for 5 seconds Lorem  ipsum  dolor  sit  amet,  consectetur   Lorem  ipsum  dolor  sit   layout adipiscing  elit.  In  vel  nulla  arcu,  vitae   amet,  consectetur   cursus  nunc.  Integer  semper  turpis  et  enim   adipiscing  elit.  In  vel  nulla   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   arcu,  vitae  cursus  nunc.   dolor  sit  amet,  consectetur  adipiscing  elit.   Integer  semper  turpis  et   Mauris  vehicula  ves;bulum  dictum.   enim  por6tor  iaculis.   Aenean  non  velit  tortor.  Nullam  adipiscing   Nulla  facilisi.  Lorem  ipsum   malesuada  aliquam.  Mauris  dignissim,  urna   dolor  sit  amet,   quis  iaculis  tempus,  justo  libero  por6tor   consectetur  adipiscing  elit.   est,  nec  eleifend  est  elit  vitae  ante.   Mauris  vehicula   Curabitur  interdum  luctus  metus,  in   ves;bulum  dictum.   pulvinar  lectus  rutrum  sit  amet.  Duis   Aenean  non  velit  tortor.   gravida,  metus  in  dictum  eleifend,  dolor   Nullam  adipiscing   risus  ;ncidunt  ligula,  non  volutpat  nulla   malesuada  aliquam.   sapien  main Nulla  rutrum  erat  id  neque   in  elit.   Mauris  embeddedurna   dignissim,   suscipit  eu  ultricies  odio  sollicitudin.   controller quis  iaculis  tempus,  justo   controller Aliquam  a  mi  vel  eros  placerat  hendrerit.   libero  por6tor  est,  nec   Phasellus  por6tor,  augue  sit  amet   eleifend  est  elit  vitae  ante.   vulputate  venena;s,  dui  leo  commodo   Curabitur  interdum  luctus   odio,  a  euismod  turpis  ligula  in  elit.     metus.  
  • 106. cacheable for 10 seconds <?php $view->extend('...:layout') ?> <?php $view['slots']->start('sidebar') ?> 5 seconds cacheable for <?php echo $view['actions']->render('...:foo') ?> <?php $view['slots']->stop() ?>
  • 107. $view['actions']->render('HelloBundle:Hello:foo', array('name' => $name), array('standalone' => true) )
  • 108. Lorem  ipsum  dolor  sit  amet,  consectetur   Lorem  ipsum  dolor  sit   adipiscing  elit.  In  vel  nulla  arcu,  vitae   amet,  consectetur   cursus  nunc.  Integer  semper  turpis  et  enim   adipiscing  elit.  In  vel  nulla   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   arcu,  vitae  cursus  nunc.   dolor  sit  amet,  consectetur  adipiscing  elit.   Integer  semper  turpis  et   Mauris  vehicula  ves;bulum  dictum.   enim  por6tor  iaculis.   Aenean  non  velit  tortor.  Nullam  adipiscing   Nulla  facilisi.  Lorem  ipsum   malesuada  aliquam.  Mauris  dignissim,  urna   dolor  sit  amet,   quis  iaculis  tempus,  justo  libero  por6tor   consectetur  adipiscing  elit.   est,  nec  eleifend  est  elit  vitae  ante.   Mauris  vehicula   Curabitur  interdum  luctus  metus,  in   ves;bulum  dictum.   pulvinar  lectus  rutrum  sit  amet.  Duis   Aenean  non  velit  tortor.   gravida,  metus  in  dictum  eleifend,  dolor   Nullam  adipiscing   risus  ;ncidunt  ligula,  non  volutpat  nulla   malesuada  aliquam.   sapien  in  elit.  Nulla  rutrum  erat  id  neque   Mauris  dignissim,  urna   suscipit  eu  ultricies  odio  sollicitudin.   quis  iaculis  tempus,  justo   Aliquam  a  mi  vel  eros  placerat  hendrerit.   libero  por6tor  est,  nec   Phasellus  por6tor,  augue  sit  amet   eleifend  est  elit  vitae  ante.   vulputate  venena;s,  dui  leo  commodo   Curabitur  interdum  luctus   odio,  a  euismod  turpis  ligula  in  elit.     metus.  
  • 109. <esi:include src="..." /> Lorem  ipsum  dolor  sit  amet,  consectetur   adipiscing  elit.  In  vel  nulla  arcu,  vitae   cursus  nunc.  Integer  semper  turpis  et  enim   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   dolor  sit  amet,  consectetur  adipiscing  elit.   Mauris  vehicula  ves;bulum  dictum.   Aenean  non  velit  tortor.  Nullam  adipiscing   malesuada  aliquam.  Mauris  dignissim,  urna   quis  iaculis  tempus,  justo  libero  por6tor   est,  nec  eleifend  est  elit  vitae  ante.   Curabitur  interdum  luctus  metus,  in   pulvinar  lectus  rutrum  sit  amet.  Duis   gravida,  metus  in  dictum  eleifend,  dolor   risus  ;ncidunt  ligula,  non  volutpat  nulla   sapien  in  elit.  Nulla  rutrum  erat  id  neque   suscipit  eu  ultricies  odio  sollicitudin.   Aliquam  a  mi  vel  eros  placerat  hendrerit.   Phasellus  por6tor,  augue  sit  amet   vulputate  venena;s,  dui  leo  commodo   odio,  a  euismod  turpis  ligula  in  elit.    
  • 110. ESI… or Edge Side Includes
  • 111. Lorem  ipsum   dolor  sit   amet,     1 2 Symfony2 Application Lorem   ipsum   Reverse Proxy dolor   Client 3 Lorem  ipsum   Lorem   dolor  sit   ipsum   amet,     dolor   4
  • 112. Web Server Symfony2 app Requests Response
  • 113. Web Server Symfony2 HTTP proxy Symfony2 app Requests Response
  • 114. Reverse proxy Web Server Symfony2 app Requests Response
  • 115. Extensibility
  • 116. Request core.request getController() core.controller getArguments() core.view core.response Response
  • 117. Request core.request getController() core.controller core.exception getArguments() core.view core.response Response
  • 118. SwiftmailerBundle DoctrineBundle ZendBundle ... FrameworkBundle TwigBundle Bundles Components HttpKernel DependencyInjection Console Routing Templating HttpFoundation Event Dispatcher ...
  • 119. Questions?