Fabien Potencier
A bit of history
symfony 1.0 – January 2007
•  Started as a glue between existing Open-Source libraries:
   – Mojavi (heavily modified), Pro...
symfony 1.2 – November 2008
•  Based on decoupled but cohesive components

   –  Forms, Routing, Cache, YAML, ORMs, …

•  ...
symfony 1.4 – November 2009
•  Added some polish on existing features

•  Removed the support for deprecated features

•  ...
Symfony Components
  YAML
  Dependency Injection Container
  Event Dispatcher
  Templating
  Routing
  Console
  Output Es...
What is Symfony 2?
Symfony 2 is the next version
        of the symfony framework…

except Symfony now takes a S instead of a s
Talk about
Symfony 2
     or
 symfony 1
To make it clear:
      Symfony 1
does not make any sense
symfony 2
does not make more sense
Symfony 2
Same philosophy,
   just better
MVC
hmmm,
now that I think about it…
…it’s now probably more
a Fabien’s style framework
    than anything else
Highly configurable
    Highly extensible
Same Symfony Components
Same great developer tools
      Full-featured
Ok, but why a major version then?
Symfony 2 has
    a brand new
low-level architecture
PHP 5.3
A Quick Tour
<?php

require_once __DIR__.'/../blog/BlogKernel.php';

$kernel = new BlogKernel('prod', false);
$kernel->run();
<?php                             Everything is namespaced
namespace ApplicationHelloBundleController;

use SymfonyFramewo...
Layout

<?php $view->extend('HelloBundle::layout') ?>

Hello <?php echo $name ?>!
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
  </head>
  <body>
    <?php $vi...
hello:
  pattern: /hello/:name
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:     index
hello:
  pattern: /hello/:name
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:     index

nam...
hello:
  pattern: /hello/:name
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:     index

nam...
hello:
  pattern: /hello/:name
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:     index

nam...
hello:
  pattern: /hello/:name
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:     index

nam...
hello:
  pattern: /hello/:name
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:     index

nam...
hello:
  pattern: /hello/:year/:month/:slug
  defaults:
    _bundle:     HelloBundle
    _controller: Hello
    _action:  ...
Extremely
Configurable
Dependency
 Injection
 Container
Replaces a lot of symfony 1 “things”
                     sfConfig
                  All config handlers
         sfProject...
in one
   easy-to-master
       unified
and cohesive package
Thanks to the DIC,
Configuration has never been
   so easy and so flexible
Name your configuration files
     the way you want
Store them where you want
Use PHP, XML, YAML, or INI
$configuration = new BuilderConfiguration();
$configuration->addResource(new FileResource(__FILE__));

$configuration
  ->...
web.user:
    default_culture: fr
    session: { name: SYMFONY, type: Native, lifetime: 3600 }

web.templating:
  escaping...
<web:user default_culture="fr">
  <web:session name="SYMFONY" type="Native" lifetime="3600" />
</web:user>

<web:templatin...
$configuration->mergeExtension('swift.mailer', array(
    'transport' => 'gmail',
    'username' => 'fabien.potencier',
  ...
swift.mailer:
  transport: gmail
  username: fabien.potencier
  password: xxxxxxxx

                               YAML	
  
<swift:mailer
  transport="gmail"
  username="fabien.potencier"
  password="xxxxxxxx" />

                                ...
<?xml version="1.0" ?>

<container xmlns="http://www.symfony-project.org/schema/dic/services"
    xmlns:xsi="http://www.w3...
<?xml version="1.0" ?>

<container xmlns="http://www.symfony-project.org/schema/dic/services"
    xmlns:xsi="http://www.w3...
Inherit them as much as you want
Mix and match
configuration files written in any
            format
   useful when using third-party plugins
<imports>
  <import resource="parent.xml" />
  <import resource="config.yml" />
                                     Mix a...
You choose the format you want

                       Pros                    Cons
 XML                   validation     ...
Store sensitive settings
 outside of your project
<doctrine:dbal
   dbname="sfweb"
   username="root"
   password="SuperSecretPasswordThatAnyoneCanSee"
/>
in a .htaccess or httpd.conf file

SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar"
                             %doctrine...
Semantic
Configuration
<swift:mailer
  transport="gmail"
  username="fabien.potencier"
  password="xxxxxxxx" />

                                ...
<swift:mailer
   transport="smtp"
   encryption="ssl"
   auth_mode="login"
   host="smtp.gmail.com"
   username="fabien.po...
<parameters>



        <parameter key="swiftmailer.class">Swift_Mailer</parameter>
  <parameter key="swiftmailer.transpor...
Creating DIC extensions
   is insanely simple
Very Fast
  thanks to a Smart
 Caching mechanism
it always knows when to flush the cache
/**
  * Gets the 'swiftmailer.mailer' service.
  *
  * This service is shared.
  * This method always returns the same ins...
The DIC can manage
ANY PHP object (POPO)
Plugins…
or Bundles
Plugins are first-class citizens
   They are called Bundles
Everything is a bundle
       Core features
     Third-party code
     Application code
app/
src/
web/
app/
  AppKernel.php
  cache/
  config/
  console
  logs/
src/
  autoload.php
  Application/
  Bundle/
  vendor/
     doctrine/
     swiftmailer/
     symfony/
     zend/
web/
  index.php
  index_dev.php
.../
  SomeBundle/
     Bundle.php
     Controller/
     Model/
     Resources/
       config/
       views/
public function registerBundleDirs()
{
  return array(
     'Application'        => __DIR__.'/../src/Application',
     'B...
$this->render('SomeBundle:Hello:index', $params)
hello:
  pattern: /hello/:name
  defaults: { _bundle: SomeBundle, ... }
SomeBundle can be any of


ApplicationSomeBundle
BundleSomeBundle
SymfonyFrameworkSomeBundle
Less concepts…
but more powerful ones
symfony 1 View Layer
         templates
           layouts
             slots
        components
           partials
     ...
Symfony 2 View Layer

       templates
         slots
A layout is just another template with _content as a special slot

A partial is just a template you embed in another one

...
<?php $view->output('BlogBundle:Post:list', array('posts'
=> $posts)) ?>
<?php $view->actions->output('BlogBundle:Post:list', array
('limit' => 2)) ?>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
  </head>
  <body>
    <?php $vi...
Big and Small
Improvements
multiple level of layouts
partials can be decorated!
Better
 Logs
INFO: Matched route "blog_home" (parameters: array ( '_bundle' =>
'BlogBundle', '_controller' => 'Post', '_action' => 'ind...
INFO: Matched route "blog_post" (parameters: array ( '_bundle' =>
'BlogBundle', '_controller' => 'Post', '_action' => 'sho...
<zend:logger priority="debug" />
DEBUG: Notifying (until) event "core.request" to listener "(SymfonyFrameworkWebBundleListenerRequestParser, resolve)"
INFO...
Even Better
Exception Error Pages
An Event Better
Web Debug Toolbar
Everything you need is
at the bottom of the screen
Web Designer
 “friendly”
app/
  views/
     BlogBundle/
       Post/
          index.php
     AdminGeneratorBundle/
         DefaultTheme/
        ...
“Mount” Routing
  Configuration
blog:
  resource: BlogBundle/Resources/config/routing.yml

forum:
  resource: ForumBundle/Resources/config/routing.yml
  p...
Symfony 2
is a lazy framework
Smart Autoloading
require_once __DIR__.'/vendor/symfony/src/Symfony/Foundation/UniversalClassLoader.php';

use SymfonyFoundationUniversalCla...
lazy-loading of services
lazy-loading of listeners
lazy-loading of helpers
<?php echo $view->router->generate('blog_post', array('id'
=> $post->getId())) ?>
Symfony 2
is a “cachy” framework
blog/
  cache/
    prod/
      blogProjectContainer.php
      blogUrlGenerator.php
      blogUrlMatcher.php
      classes....
class blogUrlMatcher extends SymfonyComponentsRoutingMatcherUrlMatcher
{
  public function __construct(array $context = ar...
You can use Apache
for Routing matching
A Very Fast
 Dev. Env.
blog/
  cache/
    dev/
      blogProjectContainer.meta
      blogProjectContainer.php
      blogUrlGenerator.meta
      b...
Symfony 2
Easy to learn
   Easy to use
Extensible at will
Easy to learn
 Easy to use
Extensible at will
But Symfony 2 should be slow, right?
Fast as hell
Benchmark
on a simple application
2x faster
   than
Solar 1.0.0
2.5x faster
    than
symfony 1.4.2
3x faster
        than
Zend Framework 1.10
4x faster
   than
 Lithium
6x faster
    than
CakePHP 1.2.6
60x faster
   than
  Flow3
…and Symfony 2.0 uses
    half the memory
needed by both symfony 1 and ZF
We have barely scratched the surface
       of all the goodness of
            Symfony 2.0
Controller                   except for the nice default pages
Autoloading
Cache                        via ZF - DI extens...
Final Release Target Date
      Late 2010
If you want the bleeding edge of news, follow me


         on Twitter @fabpot
    on Github github.com/fabpot
…
http://symfony-reloaded.org/
Questions?
My slides will be available on
http://slideshare.com/fabpot
Sensio S.A.
    92-98, boulevard Victor Hugo
        92 115 Clichy Cedex
              FRANCE
       Tél. : +33 1 40 99 80...
Symfony2 revealed
Symfony2 revealed
Upcoming SlideShare
Loading in...5
×

Symfony2 revealed

36,128

Published on

Symfony2 revealed

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

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

No notes for slide

Symfony2 revealed

  1. 1. Fabien Potencier
  2. 2. A bit of history
  3. 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. 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. 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. 6. Symfony Components YAML Dependency Injection Container Event Dispatcher Templating Routing Console Output Escaper Request Handler …
  7. 7. What is Symfony 2?
  8. 8. Symfony 2 is the next version of the symfony framework… except Symfony now takes a S instead of a s
  9. 9. Talk about Symfony 2 or symfony 1
  10. 10. To make it clear: Symfony 1 does not make any sense
  11. 11. symfony 2 does not make more sense
  12. 12. Symfony 2
  13. 13. Same philosophy, just better
  14. 14. MVC
  15. 15. hmmm, now that I think about it…
  16. 16. …it’s now probably more a Fabien’s style framework than anything else
  17. 17. Highly configurable Highly extensible Same Symfony Components Same great developer tools Full-featured
  18. 18. Ok, but why a major version then?
  19. 19. Symfony 2 has a brand new low-level architecture
  20. 20. PHP 5.3
  21. 21. A Quick Tour
  22. 22. <?php require_once __DIR__.'/../blog/BlogKernel.php'; $kernel = new BlogKernel('prod', false); $kernel->run();
  23. 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. 24. Layout <?php $view->extend('HelloBundle::layout') ?> Hello <?php echo $name ?>!
  25. 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. 26. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index
  27. 27. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  28. 28. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  29. 29. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  30. 30. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  31. 31. hello: pattern: /hello/:name defaults: _bundle: HelloBundle _controller: Hello _action: index namespace ApplicationHelloBundleController; class HelloController extends Controller { public function indexAction($name) { // ... } }
  32. 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. 33. Extremely Configurable
  34. 34. Dependency Injection Container
  35. 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. 36. in one easy-to-master unified and cohesive package
  37. 37. Thanks to the DIC, Configuration has never been so easy and so flexible
  38. 38. Name your configuration files the way you want
  39. 39. Store them where you want
  40. 40. Use PHP, XML, YAML, or INI
  41. 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. 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. 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. 44. $configuration->mergeExtension('swift.mailer', array( 'transport' => 'gmail', 'username' => 'fabien.potencier', 'password' => 'xxxxxx', )); PHP  
  45. 45. swift.mailer: transport: gmail username: fabien.potencier password: xxxxxxxx YAML  
  46. 46. <swift:mailer transport="gmail" username="fabien.potencier" password="xxxxxxxx" /> XML  
  47. 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. 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. 49. Inherit them as much as you want
  50. 50. Mix and match configuration files written in any format useful when using third-party plugins
  51. 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. 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. 53. Store sensitive settings outside of your project
  54. 54. <doctrine:dbal dbname="sfweb" username="root" password="SuperSecretPasswordThatAnyoneCanSee" />
  55. 55. in a .htaccess or httpd.conf file SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar" %doctrine.dbal.password%
  56. 56. Semantic Configuration
  57. 57. <swift:mailer transport="gmail" username="fabien.potencier" password="xxxxxxxx" /> XML  
  58. 58. <swift:mailer transport="smtp" encryption="ssl" auth_mode="login" host="smtp.gmail.com" username="fabien.potencier" password="xxxxxxxx" /> XML  
  59. 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. 60. Creating DIC extensions is insanely simple
  61. 61. Very Fast thanks to a Smart Caching mechanism it always knows when to flush the cache
  62. 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. 63. The DIC can manage ANY PHP object (POPO)
  64. 64. Plugins…
  65. 65. or Bundles
  66. 66. Plugins are first-class citizens They are called Bundles
  67. 67. Everything is a bundle Core features Third-party code Application code
  68. 68. app/ src/ web/
  69. 69. app/ AppKernel.php cache/ config/ console logs/
  70. 70. src/ autoload.php Application/ Bundle/ vendor/ doctrine/ swiftmailer/ symfony/ zend/
  71. 71. web/ index.php index_dev.php
  72. 72. .../ SomeBundle/ Bundle.php Controller/ Model/ Resources/ config/ views/
  73. 73. public function registerBundleDirs() { return array( 'Application' => __DIR__.'/../src/Application', 'Bundle' => __DIR__.'/../src/Bundle', 'SymfonyFramework' => __DIR__.'/../src/vendor/ symfony/src/Symfony/Framework', ); }
  74. 74. $this->render('SomeBundle:Hello:index', $params)
  75. 75. hello: pattern: /hello/:name defaults: { _bundle: SomeBundle, ... }
  76. 76. SomeBundle can be any of ApplicationSomeBundle BundleSomeBundle SymfonyFrameworkSomeBundle
  77. 77. Less concepts… but more powerful ones
  78. 78. symfony 1 View Layer templates layouts slots components partials component slots
  79. 79. Symfony 2 View Layer templates slots
  80. 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. 81. <?php $view->output('BlogBundle:Post:list', array('posts' => $posts)) ?>
  82. 82. <?php $view->actions->output('BlogBundle:Post:list', array ('limit' => 2)) ?>
  83. 83. <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <?php $view->slots->output('_content') ?> </body> </html>
  84. 84. Big and Small Improvements
  85. 85. multiple level of layouts
  86. 86. partials can be decorated!
  87. 87. Better Logs
  88. 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. 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. 90. <zend:logger priority="debug" />
  91. 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. 92. Even Better Exception Error Pages
  93. 93. An Event Better Web Debug Toolbar
  94. 94. Everything you need is at the bottom of the screen
  95. 95. Web Designer “friendly”
  96. 96. app/ views/ BlogBundle/ Post/ index.php AdminGeneratorBundle/ DefaultTheme/ list.php edit.php ...
  97. 97. “Mount” Routing Configuration
  98. 98. blog: resource: BlogBundle/Resources/config/routing.yml forum: resource: ForumBundle/Resources/config/routing.yml prefix: /forum
  99. 99. Symfony 2 is a lazy framework
  100. 100. Smart Autoloading
  101. 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. 102. lazy-loading of services
  103. 103. lazy-loading of listeners
  104. 104. lazy-loading of helpers
  105. 105. <?php echo $view->router->generate('blog_post', array('id' => $post->getId())) ?>
  106. 106. Symfony 2 is a “cachy” framework
  107. 107. blog/ cache/ prod/ blogProjectContainer.php blogUrlGenerator.php blogUrlMatcher.php classes.php
  108. 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. 109. You can use Apache for Routing matching
  110. 110. A Very Fast Dev. Env.
  111. 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. 112. Symfony 2
  113. 113. Easy to learn Easy to use Extensible at will
  114. 114. Easy to learn Easy to use
  115. 115. Extensible at will
  116. 116. But Symfony 2 should be slow, right?
  117. 117. Fast as hell
  118. 118. Benchmark on a simple application
  119. 119. 2x faster than Solar 1.0.0
  120. 120. 2.5x faster than symfony 1.4.2
  121. 121. 3x faster than Zend Framework 1.10
  122. 122. 4x faster than Lithium
  123. 123. 6x faster than CakePHP 1.2.6
  124. 124. 60x faster than Flow3
  125. 125. …and Symfony 2.0 uses half the memory needed by both symfony 1 and ZF
  126. 126. We have barely scratched the surface of all the goodness of Symfony 2.0
  127. 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. 128. Final Release Target Date Late 2010
  129. 129. If you want the bleeding edge of news, follow me on Twitter @fabpot on Github github.com/fabpot
  130. 130.
  131. 131. http://symfony-reloaded.org/
  132. 132. Questions? My slides will be available on http://slideshare.com/fabpot
  133. 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/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×