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