Your SlideShare is downloading. ×
0
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Symfony2 revealed
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Symfony2 revealed

35,964

Published on

Symfony2 revealed

Symfony2 revealed

Published in: Technology
0 Comments
54 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
35,964
On Slideshare
0
From Embeds
0
Number of Embeds
22
Actions
Shares
0
Downloads
698
Comments
0
Likes
54
Embeds 0
No embeds

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. Fabien Potencier
  • 2. A bit of history
  • 3. symfony 1.0 – January 2007 •  Started as a glue between existing Open-Source libraries: – Mojavi (heavily modified), Propel, Prado i18n, … •  Borrowed concepts from other languages and frameworks: – Routing, CLI, functional tests, YAML, Rails helpers… •  Added new concepts to the mix – Web Debug Toolbar, admin generator, configuration cascade, …
  • 4. symfony 1.2 – November 2008 •  Based on decoupled but cohesive components –  Forms, Routing, Cache, YAML, ORMs, … •  Controller still based on Mojavi –  View, Filter Chain, …
  • 5. symfony 1.4 – November 2009 •  Added some polish on existing features •  Removed the support for deprecated features •  Current LTS release, maintained until late 2012
  • 6. Symfony Components YAML Dependency Injection Container Event Dispatcher Templating Routing Console Output Escaper Request Handler …
  • 7. What is Symfony 2?
  • 8. Symfony 2 is the next version of the symfony framework… except Symfony now takes a S instead of a s
  • 9. Talk about Symfony 2 or symfony 1
  • 10. To make it clear: Symfony 1 does not make any sense
  • 11. symfony 2 does not make more sense
  • 12. Symfony 2
  • 13. Same philosophy, just better
  • 14. MVC
  • 15. hmmm, now that I think about it…
  • 16. …it’s now probably more a Fabien’s style framework than anything else
  • 17. Highly configurable Highly extensible Same Symfony Components Same great developer tools Full-featured
  • 18. Ok, but why a major version then?
  • 19. Symfony 2 has a brand new low-level architecture
  • 20. PHP 5.3
  • 21. A Quick Tour
  • 22. <?php require_once __DIR__.'/../blog/BlogKernel.php'; $kernel = new BlogKernel('prod', false); $kernel->run();
  • 23. <?php Everything is namespaced namespace ApplicationHelloBundleController; use SymfonyFrameworkWebBundleController; class HelloController extends Controller { public function indexAction($name) Variables come from the routing { return $this->render('HelloBundle:Hello:index', array('name' => $name)); } } Template name Variables to pass to the template
  • 24. Layout <?php $view->extend('HelloBundle::layout') ?> Hello <?php echo $name ?>!
  • 25. <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <?php $view->slots->output('_content') ?> </body> </html> Helpers are objects
  • 26. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index
  • 27. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  • 28. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  • 29. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  • 30. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  • 31. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  • 32. hello: pattern: /hello/:year/:month/:slug defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($slug, $year) { // ... } }
  • 33. Extremely Configurable
  • 34. Dependency Injection Container
  • 35. Replaces a lot of symfony 1 “things” sfConfig All config handlers sfProjectConfiguration / sfApplicationConfiguration sfContext (No Singleton anymore) The configuration cache system … and some more
  • 36. in one easy-to-master unified and cohesive package
  • 37. Thanks to the DIC, Configuration has never been so easy and so flexible
  • 38. Name your configuration files the way you want
  • 39. Store them where you want
  • 40. Use PHP, XML, YAML, or INI
  • 41. $configuration = new BuilderConfiguration(); $configuration->addResource(new FileResource(__FILE__)); $configuration ->mergeExtension('web.user', array('default_culture' => 'fr', 'session' => array('name' => 'SYMFONY', 'type' => 'Native', 'lifetime' => 3600))) ->mergeExtension('doctrine.dbal', array('dbname' => 'sfweb', 'username' => 'root')) ->mergeExtension('web.templating', array('escaping' => 'htmlspecialchars', 'assets_version' => 'SomeVersionScheme')) ->mergeExtension('swift.mailer', array('transport' => 'gmail', 'username' => 'fabien.potencier', 'password' => 'xxxxxx')) PHP   ;
  • 42. web.user: default_culture: fr session: { name: SYMFONY, type: Native, lifetime: 3600 } web.templating: escaping: htmlspecialchars assets_version: SomeVersionScheme doctrine.dbal: { dbname: sfweb, username: root, password: null } swift.mailer: transport: gmail username: fabien.potencier password: xxxxxxxx YAML  
  • 43. <web:user default_culture="fr"> <web:session name="SYMFONY" type="Native" lifetime="3600" /> </web:user> <web:templating escaping="htmlspecialchars" assets_version="SomeVersionScheme" /> <doctrine:dbal dbname="sfweb" username="root" password="" /> <swift:mailer transport="gmail" username="fabien.potencier" password="xxxxxxxx" /> XML  
  • 44. $configuration->mergeExtension('swift.mailer', array( 'transport' => 'gmail', 'username' => 'fabien.potencier', 'password' => 'xxxxxx', )); PHP  
  • 45. swift.mailer: transport: gmail username: fabien.potencier password: xxxxxxxx YAML  
  • 46. <swift:mailer transport="gmail" username="fabien.potencier" password="xxxxxxxx" /> XML  
  • 47. <?xml version="1.0" ?> <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance » xmlns:doctrine="http://www.symfony-project.org/schema/dic/doctrine" xmlns:zend="http://www.symfony-project.org/schema/dic/zend" xmlns:swift="http://www.symfony-project.org/schema/dic/swiftmailer" > XML  
  • 48. <?xml version="1.0" ?> <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance » xmlns:doctrine="http://www.symfony-project.org/schema/dic/doctrine" xmlns:zend="http://www.symfony-project.org/schema/dic/zend" xmlns:swift="http://www.symfony-project.org/schema/dic/swiftmailer" xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd http://www.symfony-project.org/schema/dic/doctrine http://www.symfony-project.org/schema/dic/doctrine/doctrine-1.0.xsd http://www.symfony-project.org/schema/dic/zend http:// www.symfony-project.org/schema/dic/zend/zend-1.0.xsd http://www.symfony-project.org/schema/dic/swiftmailer http://www.symfony-project.org/schema/dic/swiftmailer/swiftmailer-1.0.xsd »> XML  
  • 49. Inherit them as much as you want
  • 50. Mix and match configuration files written in any format useful when using third-party plugins
  • 51. <imports> <import resource="parent.xml" /> <import resource="config.yml" /> Mix and match formats <import resource="parameters.ini" /> </imports> <zend:logger priority="debug" path="%kernel.logs_dir%/%kernel.environment%.log" /> <web:debug exception="%kernel.debug%" toolbar="%kernel.debug%" ide="textmate" />
  • 52. You choose the format you want Pros Cons XML validation verbose (not that much) IDE completion & help YAML concise needs the YAML component simple to read no validation easy to change no IDE auto-completion PHP flexible no validation more expressive
  • 53. Store sensitive settings outside of your project
  • 54. <doctrine:dbal dbname="sfweb" username="root" password="SuperSecretPasswordThatAnyoneCanSee" />
  • 55. in a .htaccess or httpd.conf file SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar" %doctrine.dbal.password%
  • 56. Semantic Configuration
  • 57. <swift:mailer transport="gmail" username="fabien.potencier" password="xxxxxxxx" /> XML  
  • 58. <swift:mailer transport="smtp" encryption="ssl" auth_mode="login" host="smtp.gmail.com" username="fabien.potencier" password="xxxxxxxx" /> XML  
  • 59. <parameters> <parameter key="swiftmailer.class">Swift_Mailer</parameter> <parameter key="swiftmailer.transport.smtp.class">Swift_Transport_EsmtpTransport</parameter> <parameter key="swiftmailer.transport.smtp.host">smtp.gmail.com</parameter> <parameter key="swiftmailer.transport.smtp.port">25</parameter> <parameter key="swiftmailer.transport.smtp.encryption">ssl</parameter> <parameter key="swiftmailer.transport.smtp.username">fabien.potencier</parameter> <parameter key="swiftmailer.transport.smtp.password">xxxxxx</parameter> <parameter key="swiftmailer.transport.smtp.auth_mode">login</parameter> <parameter key="swiftmailer.init_file">swift_init.php</parameter> </parameters> <services> <service id="swiftmailer.mailer" class="%swiftmailer.class%"> <argument type="service" id="swiftmailer.transport" /> <file>%swiftmailer.init_file%</file> </service> <service id="swiftmailer.transport.smtp" class="%swiftmailer.transport.smtp.class%"> <argument type="service" id="swiftmailer.transport.buffer" /> <argument type="collection"> <argument type="service" id="swiftmailer.transport.authhandler" /> </argument> <argument type="service" id="swiftmailer.transport.eventdispatcher" /> <call method="setHost"><argument>%swiftmailer.transport.smtp.host%</argument></call> <call method="setPort"><argument>%swiftmailer.transport.smtp.port%</argument></call> <call method="setEncryption"><argument>%swiftmailer.transport.smtp.encryption%</argument></call> <call method="setUsername"><argument>%swiftmailer.transport.smtp.username%</argument></call> <call method="setPassword"><argument>%swiftmailer.transport.smtp.password%</argument></call> <call method="setAuthMode"><argument>%swiftmailer.transport.smtp.auth_mode%</argument></call> </service> <service id="swiftmailer.transport.buffer" class="Swift_Transport_StreamBuffer"> <argument type="service" id="swiftmailer.transport.replacementfactory" /> </service> <service id="swiftmailer.transport.authhandler" class="Swift_Transport_Esmtp_AuthHandler"> <argument type="collection"> <argument type="service"><service class="Swift_Transport_Esmtp_Auth_CramMd5Authenticator" /></argument> <argument type="service"><service class="Swift_Transport_Esmtp_Auth_LoginAuthenticator" /></argument> <argument type="service"><service class="Swift_Transport_Esmtp_Auth_PlainAuthenticator" /></argument> </argument> XML   </service> <service id="swiftmailer.transport.eventdispatcher" class="Swift_Events_SimpleEventDispatcher" /> <service id="swiftmailer.transport.replacementfactory" class="Swift_StreamFilters_StringReplacementFilterFactory" /> <service id="swiftmailer.transport" alias="swiftmailer.transport.smtp" /> </services>
  • 60. Creating DIC extensions is insanely simple
  • 61. Very Fast thanks to a Smart Caching mechanism it always knows when to flush the cache
  • 62. /** * Gets the 'swiftmailer.mailer' service. * * This service is shared. * This method always returns the same instance of the service. * * @return Swift_Mailer A Swift_Mailer instance. PHPDoc for auto-completion */ protected function getSwiftmailer_MailerService() { if (isset($this->shared['swiftmailer.mailer'])) return $this->shared['swiftmailer.mailer']; As fast as it could be $instance = new Swift_Mailer($this->getSwiftmailer_Transport_SmtpService()); return $this->shared['swiftmailer.mailer'] = $instance; }
  • 63. The DIC can manage ANY PHP object (POPO)
  • 64. Plugins…
  • 65. or Bundles
  • 66. Plugins are first-class citizens They are called Bundles
  • 67. Everything is a bundle Core features Third-party code Application code
  • 68. app/ src/ web/
  • 69. app/ AppKernel.php cache/ config/ console logs/
  • 70. src/ autoload.php Application/ Bundle/ vendor/ doctrine/ swiftmailer/ symfony/ zend/
  • 71. web/ index.php index_dev.php
  • 72. .../ SomeBundle/ Bundle.php Controller/ Model/ Resources/ config/ views/
  • 73. public function registerBundleDirs() { return array( 'Application' => __DIR__.'/../src/Application', 'Bundle' => __DIR__.'/../src/Bundle', 'SymfonyFramework' => __DIR__.'/../src/vendor/ symfony/src/Symfony/Framework', ); }
  • 74. $this->render('SomeBundle:Hello:index', $params)
  • 75. hello: pattern: /hello/:name defaults: { _bundle: SomeBundle, ... }
  • 76. SomeBundle can be any of ApplicationSomeBundle BundleSomeBundle SymfonyFrameworkSomeBundle
  • 77. Less concepts… but more powerful ones
  • 78. symfony 1 View Layer templates layouts slots components partials component slots
  • 79. Symfony 2 View Layer templates slots
  • 80. A layout is just another template with _content as a special slot A partial is just a template you embed in another one A component is just another action embedded in a template
  • 81. <?php $view->output('BlogBundle:Post:list', array('posts' => $posts)) ?>
  • 82. <?php $view->actions->output('BlogBundle:Post:list', array ('limit' => 2)) ?>
  • 83. <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <?php $view->slots->output('_content') ?> </body> </html>
  • 84. Big and Small Improvements
  • 85. multiple level of layouts
  • 86. partials can be decorated!
  • 87. Better Logs
  • 88. 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 ())
  • 89. 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"
  • 90. <zend:logger priority="debug" />
  • 91. 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)"
  • 92. Even Better Exception Error Pages
  • 93. An Event Better Web Debug Toolbar
  • 94. Everything you need is at the bottom of the screen
  • 95. Web Designer “friendly”
  • 96. app/ views/ BlogBundle/ Post/ index.php AdminGeneratorBundle/ DefaultTheme/ list.php edit.php ...
  • 97. “Mount” Routing Configuration
  • 98. blog: resource: BlogBundle/Resources/config/routing.yml forum: resource: ForumBundle/Resources/config/routing.yml prefix: /forum
  • 99. Symfony 2 is a lazy framework
  • 100. Smart Autoloading
  • 101. require_once __DIR__.'/vendor/symfony/src/Symfony/Foundation/UniversalClassLoader.php'; use SymfonyFoundationUniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( 'Symfony' => __DIR__.'/vendor/symfony/src', 'Application' => __DIR__, 'Bundle' => __DIR__, 'Doctrine' => __DIR__.'/vendor/doctrine/lib', )); $loader->registerPrefixes(array( 'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes', 'Zend_' => __DIR__.'/vendor/zend/library', )); $loader->register(); // for Zend Framework & SwiftMailer set_include_path(__DIR__.'/vendor/zend/library'.PATH_SEPARATOR.__DIR__.'/vendor/ swiftmailer/lib'.PATH_SEPARATOR.get_include_path());
  • 102. lazy-loading of services
  • 103. lazy-loading of listeners
  • 104. lazy-loading of helpers
  • 105. <?php echo $view->router->generate('blog_post', array('id' => $post->getId())) ?>
  • 106. Symfony 2 is a “cachy” framework
  • 107. blog/ cache/ prod/ blogProjectContainer.php blogUrlGenerator.php blogUrlMatcher.php classes.php
  • 108. class blogUrlMatcher extends SymfonyComponentsRoutingMatcherUrlMatcher { public function __construct(array $context = array(), array $defaults = array()) { $this->context = $context; $this->defaults = $defaults; } public function match($url) { $url = $this->normalizeUrl($url); if (0 === strpos($url, '/webblog') && preg_match('#^/webblog/(? P<id>[^/.]+?)$#x', $url, $matches)) return array_merge($this->mergeDefaults($matches, array ( '_bundle' => 'WebBundle', '_controller' => 'Redirect', '_action' => 'redirect', 'route' => 'blog_post',)), array('_route' => 'old_blog_post_redirect'));
  • 109. You can use Apache for Routing matching
  • 110. A Very Fast Dev. Env.
  • 111. blog/ cache/ dev/ blogProjectContainer.meta blogProjectContainer.php blogUrlGenerator.meta blogUrlGenerator.php blogUrlMatcher.meta blogUrlMatcher.php classes.meta classes.php prod/ blogProjectContainer.php blogUrlGenerator.php blogUrlMatcher.php classes.php
  • 112. Symfony 2
  • 113. Easy to learn Easy to use Extensible at will
  • 114. Easy to learn Easy to use
  • 115. Extensible at will
  • 116. But Symfony 2 should be slow, right?
  • 117. Fast as hell
  • 118. Benchmark on a simple application
  • 119. 2x faster than Solar 1.0.0
  • 120. 2.5x faster than symfony 1.4.2
  • 121. 3x faster than Zend Framework 1.10
  • 122. 4x faster than Lithium
  • 123. 6x faster than CakePHP 1.2.6
  • 124. 60x faster than Flow3
  • 125. …and Symfony 2.0 uses half the memory needed by both symfony 1 and ZF
  • 126. We have barely scratched the surface of all the goodness of Symfony 2.0
  • 127. Controller except for the nice default pages Autoloading Cache via ZF - DI extension coming soon CLI commands still missing Configuration Database via Doctrine DBAL Debug except Timer and extended WDT Escaper Event Dispatcher Form / Validation / Widget can use the 1.4 version as is Admin Generator Helpers I18n / L10n can use the 1.4 version as is Logger via ZF Mailer except commands Bundles except installing Doctrine Plugin just the DBAL part Propel Plugin Request / Response Routing no REST support, no Object support Storage / User Test View
  • 128. Final Release Target Date Late 2010
  • 129. If you want the bleeding edge of news, follow me on Twitter @fabpot on Github github.com/fabpot
  • 130. …
  • 131. http://symfony-reloaded.org/
  • 132. Questions? My slides will be available on http://slideshare.com/fabpot
  • 133. Sensio S.A. 92-98, boulevard Victor Hugo 92 115 Clichy Cedex FRANCE Tél. : +33 1 40 99 80 80 Contact Fabien Potencier fabien.potencier at sensio.com http://www.sensiolabs.com/ http://www.symfony-project.org/ http://fabien.potencier.org/

×