symfony2 revealed

135
Fabien Potencier

Upload: fabien-potencier

Post on 06-May-2015

35.806 views

Category:

Technology


0 download

DESCRIPTION

Symfony2 revealed

TRANSCRIPT

Page 1: Symfony2 revealed

Fabien Potencier

Page 2: Symfony2 revealed

A bit of history

Page 3: Symfony2 revealed

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, …

Page 4: Symfony2 revealed

symfony 1.2 – November 2008 •  Based on decoupled but cohesive components

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

•  Controller still based on Mojavi

–  View, Filter Chain, …

Page 5: Symfony2 revealed

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

•  Removed the support for deprecated features

•  Current LTS release, maintained until late 2012

Page 6: Symfony2 revealed

Symfony Components YAML Dependency Injection Container Event Dispatcher Templating Routing Console Output Escaper Request Handler …

Page 7: Symfony2 revealed

What is Symfony 2?

Page 8: Symfony2 revealed

Symfony 2 is the next version of the symfony framework…

except Symfony now takes a S instead of a s

Page 9: Symfony2 revealed

Talk about Symfony 2

or symfony 1

Page 10: Symfony2 revealed

To make it clear: Symfony 1

does not make any sense

Page 11: Symfony2 revealed

symfony 2 does not make more sense

Page 12: Symfony2 revealed

Symfony 2

Page 13: Symfony2 revealed

Same philosophy, just better

Page 14: Symfony2 revealed

MVC

Page 15: Symfony2 revealed

hmmm, now that I think about it…

Page 16: Symfony2 revealed

…it’s now probably more a Fabien’s style framework

than anything else

Page 17: Symfony2 revealed

Highly configurable Highly extensible

Same Symfony Components Same great developer tools

Full-featured

Page 18: Symfony2 revealed

Ok, but why a major version then?

Page 19: Symfony2 revealed

Symfony 2 has a brand new

low-level architecture

Page 20: Symfony2 revealed

PHP 5.3

Page 21: Symfony2 revealed

A Quick Tour

Page 22: Symfony2 revealed

<?php

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

$kernel = new BlogKernel('prod', false); $kernel->run();

Page 23: Symfony2 revealed

<?php

namespace Application\HelloBundle\Controller;

use Symfony\Framework\WebBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { return $this->render('HelloBundle:Hello:index', array('name' => $name)); } }

Everything is namespaced

Template name Variables to pass to the template

Variables come from the routing

Page 24: Symfony2 revealed

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

Hello <?php echo $name ?>!

Layout

Page 25: Symfony2 revealed

<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

Page 26: Symfony2 revealed

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

Page 27: Symfony2 revealed

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

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 28: Symfony2 revealed

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

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 29: Symfony2 revealed

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

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 30: Symfony2 revealed

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

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 31: Symfony2 revealed

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

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 32: Symfony2 revealed

hello: pattern: /hello/:year/:month/:slug defaults: _bundle: HelloBundle _controller: Hello _action: index

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($slug, $year) { // ... } }

Page 33: Symfony2 revealed

Extremely Configurable

Page 34: Symfony2 revealed

Dependency Injection Container

Page 35: Symfony2 revealed

Replaces a lot of symfony 1 “things” sfConfig

All config handlers sfProjectConfiguration / sfApplicationConfiguration

sfContext (No Singleton anymore) The configuration cache system

… and some more

Page 36: Symfony2 revealed

in one easy-to-master

unified and cohesive package

Page 37: Symfony2 revealed

Thanks to the DIC, Configuration has never been

so easy and so flexible

Page 38: Symfony2 revealed

Name your configuration files the way you want

Page 39: Symfony2 revealed

Store them where you want

Page 40: Symfony2 revealed

Use PHP, XML, YAML, or INI

Page 41: Symfony2 revealed

$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  

Page 42: Symfony2 revealed

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  

Page 43: Symfony2 revealed

<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  

Page 44: Symfony2 revealed

$configuration->mergeExtension('swift.mailer', array( 'transport' => 'gmail', 'username' => 'fabien.potencier', 'password' => 'xxxxxx', ));

PHP  

Page 45: Symfony2 revealed

swift.mailer: transport: gmail username: fabien.potencier password: xxxxxxxx

YAML  

Page 46: Symfony2 revealed

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

XML  

Page 47: Symfony2 revealed

<?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  

Page 48: Symfony2 revealed

<?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  

Page 49: Symfony2 revealed
Page 50: Symfony2 revealed

Inherit them as much as you want

Page 51: Symfony2 revealed

Mix and match configuration files written in any

format

useful when using third-party plugins

Page 52: Symfony2 revealed

<imports> <import resource="parent.xml" /> <import resource="config.yml" /> <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" />

Mix and match formats

Page 53: Symfony2 revealed

You choose the format you want

Pros Cons XML validation

IDE completion & help verbose (not that much)

YAML concise simple to read easy to change

needs the YAML component no validation no IDE auto-completion

PHP flexible more expressive

no validation

Page 54: Symfony2 revealed

Store sensitive settings outside of your project

Page 55: Symfony2 revealed

<doctrine:dbal dbname="sfweb" username="root" password="SuperSecretPasswordThatAnyoneCanSee" />

Page 56: Symfony2 revealed

SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar"

in a .htaccess or httpd.conf file

%doctrine.dbal.password%

Page 57: Symfony2 revealed

Semantic Configuration

Page 58: Symfony2 revealed

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

XML  

Page 59: Symfony2 revealed

<swift:mailer transport="smtp" encryption="ssl" auth_mode="login" host="smtp.gmail.com" username="fabien.potencier" password="xxxxxxxx" />

XML  

Page 60: Symfony2 revealed

<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> </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>

XML  

Page 61: Symfony2 revealed

Creating DIC extensions is insanely simple

Page 62: Symfony2 revealed

Very Fast thanks to a Smart

Caching mechanism it always knows when to flush the cache

Page 63: Symfony2 revealed

/** * 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. */ protected function getSwiftmailer_MailerService() { if (isset($this->shared['swiftmailer.mailer'])) return $this->shared['swiftmailer.mailer'];

$instance = new Swift_Mailer($this->getSwiftmailer_Transport_SmtpService());

return $this->shared['swiftmailer.mailer'] = $instance; }

PHPDoc for auto-completion

As fast as it could be

Page 64: Symfony2 revealed

The DIC can manage ANY PHP object (POPO)

Page 65: Symfony2 revealed

Plugins…

Page 66: Symfony2 revealed

or Bundles

Page 67: Symfony2 revealed

Plugins are first-class citizens They are called Bundles

Page 68: Symfony2 revealed

Everything is a bundle Core features

Third-party code Application code

Page 69: Symfony2 revealed

app/ src/ web/

Page 70: Symfony2 revealed

app/ AppKernel.php cache/ config/ console logs/

Page 71: Symfony2 revealed

src/ autoload.php Application/ Bundle/ vendor/ doctrine/ swiftmailer/ symfony/ zend/

Page 72: Symfony2 revealed

web/ index.php index_dev.php

Page 73: Symfony2 revealed

.../ SomeBundle/ Bundle.php Controller/ Model/ Resources/ config/ views/

Page 74: Symfony2 revealed

public function registerBundleDirs() { return array( 'Application' => __DIR__.'/../src/Application', 'Bundle' => __DIR__.'/../src/Bundle', 'Symfony\\Framework' => __DIR__.'/../src/vendor/symfony/src/Symfony/Framework', ); }

Page 75: Symfony2 revealed

$this->render('SomeBundle:Hello:index', $params)

Page 76: Symfony2 revealed

hello: pattern: /hello/:name defaults: { _bundle: SomeBundle, ... }

Page 77: Symfony2 revealed

SomeBundle can be any of

Application\SomeBundle Bundle\SomeBundle Symfony\Framework\SomeBundle

Page 78: Symfony2 revealed

Less concepts… but more powerful ones

Page 79: Symfony2 revealed

symfony 1 View Layer templates

layouts slots

components partials

component slots

Page 80: Symfony2 revealed

Symfony 2 View Layer

templates slots

Page 81: Symfony2 revealed

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

Page 82: Symfony2 revealed

<?php $view->output('BlogBundle:Post:list', array('posts' => $posts)) ?>

Page 83: Symfony2 revealed

<?php $view->actions->output('BlogBundle:Post:list', array('limit' => 2)) ?>

Page 84: Symfony2 revealed

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <?php $view->slots->output('_content') ?> </body> </html>

Page 85: Symfony2 revealed

Big and Small Improvements

Page 86: Symfony2 revealed

multiple level of layouts

Page 87: Symfony2 revealed

partials can be decorated!

Page 88: Symfony2 revealed

Better Logs

Page 89: Symfony2 revealed

INFO: Matched route "blog_home" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'index', '_route' => 'blog_home',))

INFO: Using controller "Bundle\BlogBundle\Controller\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 ())

Page 90: Symfony2 revealed

INFO: Matched route "blog_post" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'show', '_format' => 'html', 'id' => '3456', '_route' => 'blog_post',))

INFO: Using controller "Bundle\BlogBundle\Controller\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 Symfony\Components\RequestHandler\Exception\NotFoundHttpException exception)

INFO: Using controller "Symfony\Framework\WebBundle\Controller\ExceptionController::exceptionAction"

Page 91: Symfony2 revealed

<zend:logger priority="debug" />

Page 92: Symfony2 revealed

DEBUG: Notifying (until) event "core.request" to listener "(Symfony\Framework\WebBundle\Listener\RequestParser, 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 "(Symfony\Framework\WebBundle\Listener\ControllerLoader, resolve)" INFO: Using controller "Bundle\BlogBundle\Controller\PostController::showAction" DEBUG: Listener "(Symfony\Framework\WebBundle\Listener\ControllerLoader, 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 "(Symfony\Framework\WebBundle\Listener\ExceptionHandler, handle)" ERR: Post "3456" not found! (No result was found for query although at least one row was expected.) (uncaught Symfony\Components\RequestHandler\Exception\NotFoundHttpException exception) DEBUG: Notifying (until) event "core.request" to listener "(Symfony\Framework\WebBundle\Listener\RequestParser, resolve)" DEBUG: Notifying (until) event "core.load_controller" to listener "(Symfony\Framework\WebBundle\Listener\ControllerLoader, resolve)" INFO: Using controller "Symfony\Framework\WebBundle\Controller\ExceptionController::exceptionAction" DEBUG: Listener "(Symfony\Framework\WebBundle\Listener\ControllerLoader, resolve)" processed the event "core.load_controller" DEBUG: Notifying (filter) event "core.response" to listener "(Symfony\Framework\WebBundle\Listener\ResponseFilter, filter)" DEBUG: Notifying (filter) event "core.response" to listener "(Symfony\Framework\WebBundle\Debug\DataCollector\DataCollectorManager, handle)" DEBUG: Notifying (filter) event "core.response" to listener "(Symfony\Framework\WebBundle\Debug\WebDebugToolbar, handle)" DEBUG: Listener "(Symfony\Framework\WebBundle\Listener\ExceptionHandler, handle)" processed the event "core.exception" DEBUG: Notifying (filter) event "core.response" to listener "(Symfony\Framework\WebBundle\Listener\ResponseFilter, filter)" DEBUG: Notifying (filter) event "core.response" to listener "(Symfony\Framework\WebBundle\Debug\DataCollector\DataCollectorManager, handle)" DEBUG: Notifying (filter) event "core.response" to listener "(Symfony\Framework\WebBundle\Debug\WebDebugToolbar, handle)"

Page 93: Symfony2 revealed

Even Better Exception Error Pages

Page 94: Symfony2 revealed
Page 95: Symfony2 revealed

An Event Better Web Debug Toolbar

Page 96: Symfony2 revealed

Everything you need is at the bottom of the screen

Page 97: Symfony2 revealed

Web Designer “friendly”

Page 98: Symfony2 revealed

app/ views/ BlogBundle/ Post/ index.php AdminGeneratorBundle/ DefaultTheme/ list.php edit.php ...

Page 99: Symfony2 revealed

“Mount” Routing Configuration

Page 100: Symfony2 revealed

blog: resource: BlogBundle/Resources/config/routing.yml

forum: resource: ForumBundle/Resources/config/routing.yml prefix: /forum

Page 101: Symfony2 revealed

Symfony 2 is a lazy framework

Page 102: Symfony2 revealed

Smart Autoloading

Page 103: Symfony2 revealed

require_once __DIR__.'/vendor/symfony/src/Symfony/Foundation/UniversalClassLoader.php';

use Symfony\Foundation\UniversalClassLoader;

$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());

Page 104: Symfony2 revealed

lazy-loading of services

Page 105: Symfony2 revealed

lazy-loading of listeners

Page 106: Symfony2 revealed

lazy-loading of helpers

Page 107: Symfony2 revealed

<?php echo $view->router->generate('blog_post', array('id' => $post->getId())) ?>

Page 108: Symfony2 revealed

Symfony 2 is a “cachy” framework

Page 109: Symfony2 revealed

blog/ cache/ prod/ blogProjectContainer.php blogUrlGenerator.php blogUrlMatcher.php classes.php

Page 110: Symfony2 revealed

class blogUrlMatcher extends Symfony\Components\Routing\Matcher\UrlMatcher { 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'));

Page 111: Symfony2 revealed

You can use Apache for Routing matching

Page 112: Symfony2 revealed

A Very Fast Dev. Env.

Page 113: Symfony2 revealed

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

Page 114: Symfony2 revealed

Symfony 2

Page 115: Symfony2 revealed

Easy to learn Easy to use

Extensible at will

Page 116: Symfony2 revealed

Easy to learn Easy to use

Page 117: Symfony2 revealed

Extensible at will

Page 118: Symfony2 revealed

But Symfony 2 should be slow, right?

Page 119: Symfony2 revealed

Fast as hell

Page 120: Symfony2 revealed

Benchmark on a simple application

Page 121: Symfony2 revealed

2x faster than

Solar 1.0.0

Page 122: Symfony2 revealed

2.5x faster than

symfony 1.4.2

Page 123: Symfony2 revealed

3x faster than

Zend Framework 1.10

Page 124: Symfony2 revealed

4x faster than

Lithium

Page 125: Symfony2 revealed

6x faster than

CakePHP 1.2.6

Page 126: Symfony2 revealed

60x faster than

Flow3

Page 127: Symfony2 revealed

…and Symfony 2.0 uses half the memory

needed by both symfony 1 and ZF

Page 128: Symfony2 revealed

We have barely scratched the surface of all the goodness of

Symfony 2.0

Page 129: Symfony2 revealed

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

Page 130: Symfony2 revealed

Final Release Target Date Late 2010

Page 131: Symfony2 revealed

If you want the bleeding edge of news, follow me

on Twitter @fabpot on Github github.com/fabpot

Page 132: Symfony2 revealed

Page 133: Symfony2 revealed

http://symfony-reloaded.org/

Page 134: Symfony2 revealed

Questions?

My slides will be available on http://slideshare.com/fabpot

Page 135: Symfony2 revealed

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/