SlideShare une entreprise Scribd logo
1  sur  104
Symfony 2
Fabien Potencier
             Symfony 2 | Fabien Potencier
Who am I?
•  Founder of Sensio
   – Web Agency (France and USA)
   – Since 1998
   – 70 people
   – Open-Source Specialists
   – Big corporate customers
   – Consulting, training, development, web design, …
   – Main sponsor of symfony and Doctrine

•  Creator and lead developer of symfony

              Symfony 2 | Fabien Potencier
How many of you have used symfony?
               1.0? 1.1? 1.2?


       Symfony 2 | Fabien Potencier
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, …

              Symfony 2 | Fabien Potencier
symfony 1.2 – November 2008


•  Decoupled but cohesive components: the symfony platform

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

•  Controller still based on Mojavi

    –  View, Filter Chain, …



                 Symfony 2 | Fabien Potencier
Roadmap

•  1.0 – January 2007
•  1.1 – June 2008
•  1.2 – November 2008
•  1.3 – November 2009
•  Version 2.0 …
•  1.4 – Last 1.X version
   – same as 1.3 but with all deprecated features removed
             Symfony 2 | Fabien Potencier
symfony platform
                                                             >= 1.1

                                                                      2.0


    sfRequest     sfRouting      sfLogger      sfI18N   sfUser      sfResponse




sfYAML   sfDatabase     sfForm     sfEventDispatcher    sfStorage     sfCache    sfOutputEscaper



             sfValidator        sfWidget                             sfCoreAutoload
                                                                                       platform


                Symfony 2 | Fabien Potencier
Symfony Components
•  Standalone components
•  Packaged individually
•  Upcoming dedicated website
     –  http://components.symfony-project.org/
•  Dedicated section for each component
•  Dedicated documentation
•  Dedicated Subversion repository
     –  http://svn.symfony-project.com/components/
•  Git mirror
     –  http://github.com/fabpot
•  Already published components:
     –  YAML, Dependency Injection, Event Dispatcher


                         Symfony 2 | Fabien Potencier
Symfony 2 is an evolution of symfony 1


•  Same Symfony platform / components

•  Different controller implementation

•  Oh! Symfony now takes a capital S!!!

             Symfony 2 | Fabien Potencier
Symfony 2 main goals


                           Flexibility
                                        Fast
                                 Smart
         Symfony 2 | Fabien Potencier
Symfony 2: New components


     Dependency Injection Container
            Templating Framework
                 Controller Handling

         Symfony 2 | Fabien Potencier
Symfony 2

•  Not yet available as a full-stack MVC framework
•  Some components have already been merged into Symfony 1
   –  Event Dispatcher
   –  Form Framework
•  Other new components will soon be released as standalone components:
   –  Controller Handling
   –  Templating Framework
   –  Dependency Injection Container (done)

                Symfony 2 | Fabien Potencier
symfony 1: Not fast enough?

          Symfony 2 | Fabien Potencier
symfony 1 is
  one of the slowest framework
     when you test it against
a simple Hello World application
     Symfony 2 | Fabien Potencier
1644&

1544&               !"#$%&!'!&

1344&

1144&

1444&

 ;44&
                                                               x 19.5
 :44&

 944&

 844&


        Hello World
 744&

 644&
         Benchmark
 544&

 344&
                                      ()"#*&                            x 2.3
 144&                                                    +,&       -./0)%.&123&
   4&

        based on numbers from http://paul-m-jones.com/?p=315

             Symfony 2 | Fabien Potencier
Conclusion?




Symfony 2 | Fabien Potencier
Don’t use symfony
 for your next « Hello World » website

                        Use PHP ;)



Symfony 2 | Fabien Potencier
By the way,

      the fastest implemention
of a Hello World application with PHP:

   die('Hello World');

Symfony 2 | Fabien Potencier
But symfony 1 is probably fast enough
        for your next website


     Symfony 2 | Fabien Potencier
… anyway, it is fast enough for Yahoo!

Yahoo! Bookmarks                       sf-to.org/bookmarks

Yahoo! Answers                         sf-to.org/answers

delicious.com                          sf-to.org/delicious


        Symfony 2 | Fabien Potencier
… and recently
   dailymotion.com announced
     its migration to Symfony

       sf-to.org/dailymotion


Symfony 2 | Fabien Potencier
Second most popular video sharing website
  One of the top 50 websites in the world
     42 million unique users in December


      Symfony 2 | Fabien Potencier
…and of course
many other smaller websites…



Symfony 2 | Fabien Potencier
Symfony 2: Faster?

          Symfony 2 | Fabien Potencier
Symfony 2 core is so light and flexible
   that you can easily customize it
  to have outstanding performance
     for a Hello World application

     Symfony 2 | Fabien Potencier
Symfony 2 core is so light and flexible
      that its raw performance
            is outstanding


     Symfony 2 | Fabien Potencier
require_once dirname(__FILE__).'/sf20/autoload2/sfCore2Autoload.class.php';
sfCore2Autoload::register();

$app = new HelloApplication();

                                                                                                Hello World
$app->run()->send();

class HelloApplication
                                                                                                               0
                                                                                                  h Symfony 2.
{
  public function __construct()
  {                                                                                           wit
    $this->dispatcher = new sfEventDispatcher();
    $this->dispatcher->connect('application.load_controller', array($this, 'loadController'));
  }

    public function run()
    {
      $request = new sfWebRequest($this->dispatcher);
      $handler = new sfRequestHandler($this->dispatcher);
      $response = $handler->handle($request);

        return $response;
    }

    public function loadController(sfEvent $event)
    {
      $event->setReturnValue(array(array($this, 'hello'), array($this->dispatcher, $event['request'])));

        return true;
    }

    public function hello($dispatcher, $request)
    {
      $response = new sfWebResponse($dispatcher);
      $response->setContent('Hello World');

        return $response;
    }
}
                              Symfony 2 | Fabien Potencier
7922&

7822&   !"#$%&!'!&                                                     Hello World
                                                                        Benchmark
                     ()$*+&
7022&

7722&

7222&

 >22&

 =22&

 <22&

 ;22&

 :22&
                               ,-./+%-&012&
 922&
                                              x 3              x 7
 822&

 022&
                                              3+"#4&
 722&                                                  56&      ,-./+%-&710&
   2&


        based on numbers from http://paul-m-jones.com/?p=315


                Symfony 2 | Fabien Potencier
7 times faster ?!



 You won’t have such a difference for real applications
        as most of the time, the limiting factor
              is not the framework itself


           Symfony 2 | Fabien Potencier
Twitto ?!

            Symfony 2 | Fabien Potencier
Twitto: The PHP framework that fits in a tweet

•  The fastest framework around?
•  Uses some PHP 5.3 new features
•  It also fits in a slide…

require __DIR__.'/c.php';
if (!is_callable($c = @$_GET['c'] ?:
function() { echo 'Woah!'; }))
  throw new Exception('Error');
$c();                           rg                .o
                                            twitto
             Symfony 2 | Fabien Potencier
Don’t use Twitto for your next website
            It is a joke ;)


     Symfony 2 | Fabien Potencier
7 times faster ?!

•  But raw speed matters because
   – It demonstrates that the core « kernel » is very light
   – It allows you to use several Symfony frameworks within a single
     application with the same behavior but different optimizations:

      •  One full-stack framework optimized for ease of use (think symfony 1)

      •  One light framework optimized for speed (think Rails Metal ;))

              Symfony 2 | Fabien Potencier
symfony platform
                                                                            2.0



  sfRequestHandler       sfRequest    sfRouting   sfLogger   sfI18N   sfUser      sfTemplate   sfResponse




  sfValidator   sfForm     sfWidget    sfCache    sfDatabase    sfStorage      sfYAML    sfOutputEscaper



                             sfServiceContainer      sfEventDispatcher      sfCoreAutoload
                                                                                                platform



                  Symfony 2 | Fabien Potencier
Symfony 2 kernel:
The Request Handler
         Symfony 2 | Fabien Potencier
Symfony 2 secret weapon:
The Request Handler
         Symfony 2 | Fabien Potencier
The Request Handler

•  The backbone of Symfony 2 controller implementation
•  Class to build web frameworks, not only MVC ones
•  Based on a simple assumption:
   – The input is a request object
   – The output is a response object
•  The request object can be anything you want
•  The response object must implement a send() method
              Symfony 2 | Fabien Potencier
The Request Handler

$handler = new
sfRequestHandler($dispatcher);

$request = new
sfWebRequest($dispatcher);
$response = $handler->handle($request);

$response->send();
          Symfony 2 | Fabien Potencier
The Request Handler

•  The sfRequestHandler does several things:
    – Notify events
    – Execute a callable (the controller)
    – Ensure that the Request is converted to a Response object
•  The framework is responsible for choosing the controller
•  The controller is responsible for the conversion of the Request to a
   Response

                Symfony 2 | Fabien Potencier
class sfRequestHandler
{
  protected $dispatcher = null;

    public function __construct(sfEventDispatcher $dispatcher)
    {
      $this->dispatcher = $dispatcher;
    }

    public function handle($request)
    {
      try
      {
        return $this->handleRaw($request);
      }
      catch (Exception $e)
      {
        $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.exception', array('request' => $request, 'exception' => $e)));
        if ($event->isProcessed())
        {




                                                                                                                                                                                                                        sfRequestHandler
          return $this->filterResponse($event->getReturnValue(), 'An "application.exception" listener returned a non response object.');
        }

            throw $e;
        }
    }




                                                                                                                                                                                                                        is less than 100
    public function handleRaw($request)
    {
      $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.request', array('request' => $request)));
      if ($event->isProcessed())
      {




                                                                                                                                                                                                                       lines of PHP code!
        return $this->filterResponse($event->getReturnValue(), 'An "application.request" listener returned a non response object.');
      }

        $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.load_controller', array('request' => $request)));
        if (!$event->isProcessed())
        {
          throw new Exception('Unable to load the controller.');
        }

        list($controller, $arguments) = $event->getReturnValue();

        if (!is_callable($controller))
        {
          throw new Exception(sprintf('The controller must be a callable (%s).', var_export($controller, true)));
        }

        $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.controller', array('request' => $request, 'controller' => &$controller, 'arguments' => &$arguments)));
        if ($event->isProcessed())
        {
          try
          {
             return $this->filterResponse($event->getReturnValue(), 'An "application.controller" listener returned a non response object.');
          }
          catch (Exception $e)
          {
             $retval = $event->getReturnValue();
          }
        }
        else
        {
          $retval = call_user_func_array($controller, $arguments);
        }

        $event = $this->dispatcher->filter(new sfEvent($this, 'application.view'), $retval);

        return $this->filterResponse($event->getReturnValue(), sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : (string) $event->getReturnValue()));
    }

    protected function filterResponse($response, $message)
    {
      if (!is_object($response) || !method_exists($response, 'send'))
      {
        throw new RuntimeException($message);
      }

        $event = $this->dispatcher->filter(new sfEvent($this, 'application.response'), $response);
        $response = $event->getReturnValue();

        if (!is_object($response) || !method_exists($response, 'send'))
        {
          throw new RuntimeException('An "application.response" listener returned a non response object.');
        }

        return $response;
    }
}



                                                                                  Symfony 2 | Fabien Potencier
Request Handler Events

  application.request
  application.load_controller
  application.controller
  application.view
  application.response

  application.exception
          Symfony 2 | Fabien Potencier
application.response




 As the very last event notified, a listener can modify the
    Response object just before it is returned to the user



           Symfony 2 | Fabien Potencier
application.request



•  The very firstevent notified

•  It can act as a short-circuit event

•  If one listener returns a Response object, it stops the processing

              Symfony 2 | Fabien Potencier
application.load_controller


•  Only event for which at least one listener must be connected to

•  A listener must return
   – A PHP callable (the controller)
   – The arguments to pass to the callable



              Symfony 2 | Fabien Potencier
application.view




    The controller must return a Response object
            except if a listener can convert
       the controller return value to a Response


         Symfony 2 | Fabien Potencier
application.exception




   The request handler catches all exceptions
          and give a chance to listeners
           to return a Response object


         Symfony 2 | Fabien Potencier
Request Handler

•  Several listeners can be attached to a single event
•  Listeners are called in turn
                                                       sfEventDispatcher
                                     load_controller



                                                       controller




                                                                                       response
                           request




                                                                    view
                                                                           exception


       request                                         sfRequestHandler                           response




                 Symfony 2 | Fabien Potencier
require_once dirname(__FILE__).'/sf20/autoload2/sfCore2Autoload.class.php';
sfCore2Autoload::register();

$app = new HelloApplication();
$app->run()->send();

class HelloApplication
{
  public function __construct()
  {
    $this->dispatcher = new sfEventDispatcher();

                                                                            Hello World
    $this->dispatcher->connect('application.load_controller', array($this, 'loadController'));
  }

                                                                                            nts
                                                                               fony Compone
    public function run()
    {
      $request = new sfWebRequest($this->dispatcher);                 with Sym
      $handler = new sfRequestHandler($this->dispatcher);
      $response = $handler->handle($request);
      return $response;
    }

    public function loadController(sfEvent $event)
    {
      $event->setReturnValue(array(array($this, 'hello'), array($this->dispatcher, $event['request'])));
      return true;
    }

    public function hello($dispatcher, $request)
    {
      $response = new sfWebResponse($dispatcher);
      $response->setContent('Hello World');
      return $response;
    }
}
                            Symfony 2 | Fabien Potencier
require_once '/path/to/sfCore2Autoload.class.php';
sfCore2Autoload::register();




           Symfony 2 | Fabien Potencier
$app = new HelloApplication();
$app->run()->send();




        Symfony 2 | Fabien Potencier
public function __construct()
 {
   $this->dispatcher = new sfEventDispatcher();
   $this->dispatcher->connect(
      'application.load_controller',
      array($this, 'loadController')
   );
 }                           sfEventDispatcher


                                             load_controller



                                                               controller




                                                                                               response
                                   request




                                                                            view
                                                                                   exception


                   request                                     sfRequestHandler                           response




          Symfony 2 | Fabien Potencier
public function loadController(sfEvent $event)
 {
   $event->setReturnValue(array(
    array($this, 'hello'),
    array($this->dispatcher, $event['request'])
   ));

     return true;
 }




            Symfony 2 | Fabien Potencier
public function hello($dispatcher, $request)
 {
   $response = new sfWebResponse($dispatcher);
   $response->setContent('Hello World');

     return $response;
 }




             Symfony 2 | Fabien Potencier
public function run()
 {
   $request = new sfWebRequest($this->dispatcher);
   $handler = new sfRequestHandler($this->dispatcher);
   $response = $handler->handle($request);

     return $response;
 }




             Symfony 2 | Fabien Potencier
Case study: dailymotion.com

•  The problem: the Dailymotion developers add new features on a
   nearly everyday basis
•  The challenge: Migrate by introducing small doses of Symfony
   goodness
•  The process
   – Wrap everything with sfRequestHandler by implementing an
     application.load_controller listener that calls the old code, based on the
     request
   – Migrate the mod_rewrite rules to the symfony routing
   – Add unit and functional tests

               Symfony 2 | Fabien Potencier
Symfony 2: The Templating Framework

         Symfony 2 | Fabien Potencier
New Templating Framework

•  4 components
   – Template Engine
   – Template Renderers
   – Template Loaders
   – Template Storages


•  Independant library
              Symfony 2 | Fabien Potencier
require_once '/path/to/sfCore2Autoload.class.php';
sfCore2Autoload::register();

$dispatcher = new sfEventDispatcher();

$loader = new sfTemplateLoaderFilesystem($dispatcher,
  '/path/to/templates/%s.php');

$t = new sfTemplateEngine($dispatcher, $loader);

echo $t->render('index', array('name' => 'Fabien'));

            Symfony 2 | Fabien Potencier
Template Loaders

•  No assumption about where and how templates are to be found
   – Filesystem
   – Database
   – Memory
   – …
•  Template names are « logical » names:
     $loader = new sfTemplateLoaderFilesystem($dispatcher,
                  '/path/to/templates/%s.php');


              Symfony 2 | Fabien Potencier
Template Renderers

•  No assumption about the format of the templates
•  Template names are prefixed with the renderer name:
   –  index == php:index
   –  user:index

$t = new sfTemplateEngine($dispatcher, $loader, array(
  'user' => new ProjectTemplateRenderer($dispatcher),
  'php' => new sfTemplateRendererPhp($dispatcher),
));

            Symfony 2 | Fabien Potencier
Template Embedding



Hello <?php echo $name ?>

<?php $this->render('embedded', array('name' => $name)) ?>

<?php $this->render('smarty:embedded') ?>




            Symfony 2 | Fabien Potencier
Template Inheritance

<?php $this->decorator('layout') ?>
Hello <?php echo $name ?>
<html>
  <head>
  </head>
  <body>
    <?php $this->output('content') ?>
  </body>
</html>
          Symfony 2 | Fabien Potencier
Template Slots
<html>
  <head>
    <title><?php $this->output('title') ?></title>
  </head>
  <body>
    <?php $this->output('content') ?>
  </body>
</html>

<?php $this->set('title', 'Hello World! ') ?>

<?php $this->start('title') ?>
  Hello World!
<?php $this->stop() ?>
            Symfony 2 | Fabien Potencier
Template Multiple Inheritance



         A layout can be decorated by another layout

                   Each layout can override slots



          Symfony 2 | Fabien Potencier
Templating: An example

         Symfony 2 | Fabien Potencier
CMS Templating

•  Imagine a CMS with the following features:
   – The CMS comes bundled with default templates
   – The developer can override default templates for a specific project
   – The webmaster can override some templates
•  The CMS and developer templates are stored on the filesystem
   and are written with pure PHP code
•  The webmaster templates are stored in a database and are
   written in a simple templating language: Hello {{ name }}
              Symfony 2 | Fabien Potencier
CMS Templating

•  The CMS has several built-in sections and pages
   – Each page is decorated by a layout, depending on the section
   – Each section layout is decorated by a base layout
cms/templates/                               project/templates/
  base.php                                     base.php
  articles/                                    articles/
    layout.php                                   layout.php
    article.php                                  article.php
                                                 content.php
              Symfony 2 | Fabien Potencier
articles/content.php



<h1>{{ title }}</h1>

<p>
  {{ content }}
</p>

        Symfony 2 | Fabien Potencier
articles/article.php


<?php $this->decorator('articles/layout') ?>
<?php $this->set('title', $title) ?>
<?php echo $this->render(
  'user:articles/content',
  array('title' => $title, 'content' => $content)
) ?>



          Symfony 2 | Fabien Potencier
articles/layout.php


<?php $this->decorator('base') ?>

<?php $this->set('title', 'Articles | '.$this->get('title')) ?>

<?php $this->start('head') ?>
  <?php $this->output('head') ?>
  <link rel="stylesheet" type="text/css" media="all" href="/css/
articles.css" />
<?php $this->stop() ?>

<?php $this->output('content') ?>



               Symfony 2 | Fabien Potencier
articles/layout.php




<?php $this->decorator('base') ?>

<?php $this->set('title', 'Articles | '.$this->get('title')) ?>

<?php $this->stylesheets->add('/css/articles.css') ?>

<?php $this->output('content') ?>




               Symfony 2 | Fabien Potencier
base.php
<html>
  <head>
    <title>
      <?php $this->output('title') ?>
    </title>
    <?php $this->output('head') ?>
  </head>
  <body>
    <?php $this->output('content') ?>
  </body>
</html>
           Symfony 2 | Fabien Potencier
Template Renderer



$t = new sfTemplateEngine($dispatcher, $loader, array(
  'user' => new ProjectTemplateRenderer($dispatcher),
  'php' => new sfTemplateRendererPhp($dispatcher),
));




           Symfony 2 | Fabien Potencier
Template Renderer
class ProjectTemplateRenderer extends sfTemplateRenderer
{
  public function evaluate($template, array $parameters = array())
  {
    if ($template instanceof sfTemplateStorageFile)
    {
      $template = file_get_contents($template);
    }

     $this->parameters = $parameters;

    return preg_replace_callback('/{{s*(.+?)s*}}/', array($this, 'replaceParameters'),
$template);
  }

    public function replaceParameters($matches)
    {
      return isset($this->parameters[$matches[1]]) ? $this->parameters[$matches[1]] : null;
    }
}


                     Symfony 2 | Fabien Potencier
Template Loaders



$loader = new sfTemplateLoaderFilesystem($dispatcher,
  array(
    '/path/to/project/templates/%s.php',
    '/path/to/cms/templates/%s.php'
  ));




           Symfony 2 | Fabien Potencier
Template Loader Chain


$loader = new sfTemplateLoaderChain($dispatcher, array(
  new ProjectTemplateLoader(
    $dispatcher, array('pdo' => $pdo)),
  new sfTemplateLoaderFilesystem($dispatcher, array(
   '/path/to/project/templates/%s.php',
   '/path/to/cms/templates/%s.php'
  )),
));



           Symfony 2 | Fabien Potencier
Database Template Loader
class ProjectTemplateLoader extends sfTemplateLoader
{
  public function load($template)
  {
        $stmt = $this->options['pdo']->prepare('SELECT tpl FROM tpl WHERE name = :name');
        try
        {
          $stmt->execute(array('name' => $template));
          if (count($rows = $stmt->fetchAll(PDO::FETCH_NUM)))
          {
            return $rows[0][0];
          }
        }
        catch (PDOException $e)
        {
        }

        return false;
    }
}

                        Symfony 2 | Fabien Potencier
Database Template Loader



$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE tpl (name, tpl)');
$pdo->exec('INSERT INTO tpl (name, tpl) VALUES
("articles/content", "{{ title }} {{ name }}")');




           Symfony 2 | Fabien Potencier
Template Loader Cache



$loader = new sfTemplateLoaderCache(
  $dispatcher,
  $loader,
  new sfFileCache(array('dir' => 'path/to/cache'))
);




           Symfony 2 | Fabien Potencier
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE tpl (name, tpl)');
$pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }} {{ name }}")');

$loader = new sfTemplateLoaderCache(
  $dispatcher,
  new sfTemplateLoaderChain($dispatcher, array(
    new ProjectTemplateLoader($dispatcher, array('pdo' => $pdo)),
    new sfTemplateLoaderFilesystem($dispatcher, array(
     '/path/to/project/templates/%s.php',
     '/path/to/cms/templates/%s.php'
    )),
  )),
  new sfFileCache(array('dir' => 'path/to/cache'))
);

$t = new sfTemplateEngine($dispatcher, $loader, array(
  'user' => new ProjectTemplateRenderer($dispatcher)
));

$t->render('articles/article', array('title' => 'Title', 'content' => 'Lorem...'));
                    Symfony 2 | Fabien Potencier
Symfony 2: Dependency Injection Container

          Symfony 2 | Fabien Potencier
« Dependency Injection is where components
 are given their dependencies through their
    constructors, methods, or directly into
                   fields. »

h"p://www.picocontainer.org/injec2on.html 


                            Symfony 2 | Fabien Potencier
The Symfony 2 dependency injection container
replaces several symfony 1 concepts
into one integrated system:

   – sfContext
   – sfConfiguration
   – sfConfig
   – factories.yml
   – settings.yml / logging.yml / i18n.yml
              Symfony 2 | Fabien Potencier
DI Hello World example
class Message
{
  public function __construct(OutputInterface $output, array $options)
  {
    $this->output = $output;
    $this->options = array_merge(array('with_newline' => false), $options);
  }

    public function say($msg)
    {
       $this->output->render($msg.($this->options['with_newline'] ? "n" : ''));
    }
}




                  Symfony 2 | Fabien Potencier
DI Hello World example
interface OutputInterface
{
  public function render($msg);
}

class Output implements OutputInterface
{
  public function render($msg)
  {
    echo $msg;
  }
}

class FancyOutput implements OutputInterface
{
  public function render($msg)
  {
    echo sprintf("033[33m%s033[0m", $msg);
  }
}
                   Symfony 2 | Fabien Potencier
DI Hello World example




$output = new FancyOutput();
$message = new Message($output, array('with_newline' => true));
$message->say('Hello World');




              Symfony 2 | Fabien Potencier
A DI container facilitates
objects description and object relationships,
    configures and instantiates objects


       Symfony 2 | Fabien Potencier
DI Container Hello World example


$container = new sfServiceContainerBuilder();

$container->register('output', 'FancyOutput');

$container->
  register('message', 'Message')->
  setArguments(array(new sfServiceReference('output'), array('with_newline' => true)))
;

$container->message->say('Hello World!');




                    Symfony 2 | Fabien Potencier
$message = $container->message;


           Get the configuration for the message service

     The Message constructor must be given an output service

              Get the output object from the container

   Create a Message object by passing the constructor arguments




Symfony 2 | Fabien Potencier
$message = $container->message;


                        is roughly equivalent to

                  $output = new FancyOutput();
$message = new Message($output, array('with_newline' => true));!




          Symfony 2 | Fabien Potencier
$container = new sfServiceContainerBuilder();

$container->register('output', 'FancyOutput');
$container->
  register('message', 'Message')->
  setArguments(array(new sfServiceReference('output'), array('with_newline' => true)))
;
                                                                                         PHP
$container->message->say('Hello World!');


<container>
  <services>                                                                             XML
    <service id="output" class="FancyOutput" />

    <service id="message" class="Message">
      <argument type="service" id="output" />
      <argument type="collection">
        <argument key="with_newline">true</argument>
      </argument>
    </service>
  </services>
</container>

$container = new sfServiceContainerBuilder();
$loader = new sfServiceLoaderFileXml($container);
$loader->load('services.xml');

                            Symfony 2 | Fabien Potencier
$container = new sfServiceContainerBuilder();

$container->register('output', 'FancyOutput');
$container->
  register('message', 'Message')->
  setArguments(array(new sfServiceReference('output'), array('with_newline' => true)))
;                                                                                        PHP
$container->message->say('Hello World!');


services:
  output: { class: FancyOutput }                                                         YAML
  message:
    class: Message
    arguments:
      - @output
      - { with_newline: true }

$container = new sfServiceContainerBuilder();
$loader = new sfServiceLoaderFileYaml($container);
$loader->load('services.yml');



                       Symfony 2 | Fabien Potencier
<container>
  <parameters>
    <parameter key="output.class">FancyOutput</parameter>
    <parameter key="message.options" type="collection">
      <parameter key="with_newline">true</parameter>
    </parameter>
  </parameters>

 <services>
   <service id="output" class="%output.class%" />

    <service id="message" class="Message">
      <argument type="service" id="output" />
      <argument>%message.options%</argument>
    </service>
  </services>
</container>

$container = new sfServiceContainerBuilder();
$loader = new sfServiceLoaderFileXml($container);
$loader->load('services.xml');

                    Symfony 2 | Fabien Potencier
<container>
  <imports>
    <import resource="config.xml" />
  </imports>

  <services>
    <service id="output" class="%output.class%" />
    <service id="message" class="Message">
      <argument type="service" id="output" />
      <argument>%message.options%</argument>
    </service>
  </services>
</container>

<container>
  <parameters>
    <parameter key="output.class">FancyOutput</parameter>
    <parameter key="message.options" type="collection">
      <parameter key="with_newline">true</parameter>
    </parameter>
  </parameters>
</container>

$container = new sfServiceContainerBuilder();
$loader = new sfServiceLoaderFileXml($container);
$loader->load('services.xml'); 2 | Fabien Potencier
                        Symfony
<services>
 <import resource="config.yml" class="sfServiceLoaderFileYaml" />

  <service id="output" class="%output.class%" />
  <service id="message" class="Message">
    <argument type="service" id="output" />
    <argument>%message.options%</argument>
  </service>
</services>

parameters:
  output.class: FancyOutput

 message.options: { with_newline: true }

$container = new sfServiceContainerBuilder();
$loader = new sfServiceLoaderFileXml($container);
$loader->load('services.xml');


                 Symfony 2 | Fabien Potencier
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE tpl (name, tpl)');
$pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }} {{ name }}")');

$loader = new sfTemplateLoaderCache(
  $dispatcher,
  new sfTemplateLoaderChain($dispatcher, array(
    new ProjectTemplateLoader($dispatcher, array('pdo' => $pdo)),
    new sfTemplateLoaderFilesystem($dispatcher, array(
     '/path/to/project/templates/%s.php',
     '/path/to/cms/templates/%s.php'
    )),
  )),
  new sfFileCache(array('dir' => 'path/to/cache'))
);

$t = new sfTemplateEngine($dispatcher, $loader, array(
  'user' => new ProjectTemplateRenderer($dispatcher)
));

$t->render('articles/article', array('title' => 'Title', 'content' => 'Lorem...'));

                    Symfony 2 | Fabien Potencier
$pdo = new PDO('sqlite::memory:');



<service id="pdo" class="PDO">
  <argument>sqlite::memory:</argument>
</service>




                 Symfony 2 | Fabien Potencier
$container = new sfServiceContainerBuilder();
$loader = new sfServiceLoaderFileXml($container);
$loader->load('cms.xml');

$pdo->exec('CREATE TABLE tpl (name, tpl)');
$pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }}
{{ name }}")');

echo $container->template->render('articles/article', array('title' => 'Title',
'content' => 'Lorem...'));




                 Symfony 2 | Fabien Potencier
<container>
  <imports>
    <import resource="config.yml" class="sfServiceLoaderFileYaml" />
    <import resource="template_loader.xml" />
  </imports>

  <services>
    <service id="event_dispatcher" class="sfEventDispatcher" />

    <service id="pdo" class="PDO">
      <argument>sqlite::memory:</argument>
    </service>

    <service id="template_renderer" class="ProjectTemplateRenderer" lazy="true">
      <argument type="service" id="event_dispatcher" />
    </service>

    <service id="template" class="sfTemplateEngine" lazy="true">
      <argument type="service" id="event_dispatcher" />
      <argument type="service" id="template_loader" />
      <argument type="collection">
        <argument type="service" key="user" id="template_renderer" />
      </argument>
    </service>
  </services>
</container>
                       Symfony 2 | Fabien Potencier
<services>
  <service id="template_loader_project" class="ProjectTemplateLoader">
    <argument type="service" id="event_dispatcher" />
    <argument type="collection"><argument type="service" key="pdo" id="pdo" /></argument>
  </service>

 <service id="template_loader_filesystem" class="sfTemplateLoaderFilesystem">
   <argument type="service" id="event_dispatcher" />
   <argument>%template.filesystem_pattern%</argument>
 </service>

 <service id="template_loader_chain" class="sfTemplateLoaderChain">
   <argument type="service" id="event_dispatcher" />
   <argument type="collection">
     <argument type="service" id="template_loader_project" />
     <argument type="service" id="template_loader_filesystem" />
   </argument>
 </service>

 <service id="template_loader_cache" class="sfFileCache">
   <argument type="collection"><argument key="cache_dir">%application.dir%/cache</argument></argument>
 </service>

  <service id="template_loader" class="sfTemplateLoaderCache" lazy="true">
    <argument type="service" id="event_dispatcher" />
    <argument type="service" id="template_loader_chain" />
    <argument type="service" id="template_cache" />
  </service>
</services>
                          Symfony 2 | Fabien Potencier
<services>
  <service id="template_loader" class="sfTemplateLoaderCache" lazy="true">
    <argument type="service" id="event_dispatcher" />
    <argument type="service">
      <service class="sfTemplateLoaderChain">
        <argument type="service" id="event_dispatcher" />
        <argument type="collection">
          <argument type="service">
            <service class="ProjectTemplateLoader">
              <argument type="service" id="event_dispatcher" />
              <argument type="collection"><argument type="service" key="pdo" id="pdo" /></argument>
            </service>
          </argument>
          <argument type="service">
            <service class="sfTemplateLoaderFilesystem">
              <argument type="service" id="event_dispatcher" />
              <argument>%template.filesystem_patterns%</argument>
            </service>
          </argument>
        </argument>
      </service>
    </argument>
    <argument type="service">
      <service class="sfFileCache">
        <argument type="collection"><argument key="cache_dir">%application.dir%/cache</argument></argument>
      </service>
    </argument>
  </service>
</services>

                          Symfony 2 | Fabien Potencier
Symfony 2 | Fabien Potencier
Questions?

         Symfony 2 | Fabien Potencier
Sensio S.A.
                     92-98, boulevardVictor 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/



Symfony 2 | Fabien Potencier

Contenu connexe

En vedette

Building A Platform From Open Source At Yahoo
Building A Platform From Open Source At YahooBuilding A Platform From Open Source At Yahoo
Building A Platform From Open Source At Yahoonarkoza
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2Javier Eguiluz
 
History of english literature sajid
History of english literature sajidHistory of english literature sajid
History of english literature sajidDr. Cupid Lucid
 
A comprehensive grammar of the english language quirk greenbaum leech svartvik
A comprehensive grammar of the english language quirk greenbaum leech svartvikA comprehensive grammar of the english language quirk greenbaum leech svartvik
A comprehensive grammar of the english language quirk greenbaum leech svartvikIvana Jovanovic
 
PPT ON ENGLISH
PPT ON ENGLISHPPT ON ENGLISH
PPT ON ENGLISHTime Rahul
 

En vedette (6)

Building A Platform From Open Source At Yahoo
Building A Platform From Open Source At YahooBuilding A Platform From Open Source At Yahoo
Building A Platform From Open Source At Yahoo
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
 
30 Symfony Best Practices
30 Symfony Best Practices30 Symfony Best Practices
30 Symfony Best Practices
 
History of english literature sajid
History of english literature sajidHistory of english literature sajid
History of english literature sajid
 
A comprehensive grammar of the english language quirk greenbaum leech svartvik
A comprehensive grammar of the english language quirk greenbaum leech svartvikA comprehensive grammar of the english language quirk greenbaum leech svartvik
A comprehensive grammar of the english language quirk greenbaum leech svartvik
 
PPT ON ENGLISH
PPT ON ENGLISHPPT ON ENGLISH
PPT ON ENGLISH
 

Similaire à Symfony Live 09 Symfony 2

Symfony Components
Symfony ComponentsSymfony Components
Symfony Componentsguest0de7c2
 
Symfony 2.0
Symfony 2.0Symfony 2.0
Symfony 2.0GrUSP
 
Symfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projectsSymfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projectsXavier Lacot
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Fabien Potencier
 
Symfony Nano Framework
Symfony Nano FrameworkSymfony Nano Framework
Symfony Nano FrameworkLoïc Faugeron
 
Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fwdays
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkRyan Weaver
 
A Glymse of Symfony 2
A Glymse of Symfony 2A Glymse of Symfony 2
A Glymse of Symfony 2shaduli
 
Nice performance using Sf2 cache wrapping Sf1 application - Paris
Nice performance using Sf2 cache wrapping Sf1 application - ParisNice performance using Sf2 cache wrapping Sf1 application - Paris
Nice performance using Sf2 cache wrapping Sf1 application - ParisMarc Weistroff
 
An introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersAn introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersGiorgio Cefaro
 
Welcome to the Symfony2 World - FOSDEM 2013
 Welcome to the Symfony2 World - FOSDEM 2013 Welcome to the Symfony2 World - FOSDEM 2013
Welcome to the Symfony2 World - FOSDEM 2013Lukas Smith
 
Nice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 applicationNice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 applicationMarc Weistroff
 
Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...
Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...
Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...Les-Tilleuls.coop
 

Similaire à Symfony Live 09 Symfony 2 (20)

Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
 
Symfony 2.0
Symfony 2.0Symfony 2.0
Symfony 2.0
 
Symfony 2 (PHP day 2009)
Symfony 2 (PHP day 2009)Symfony 2 (PHP day 2009)
Symfony 2 (PHP day 2009)
 
Symfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projectsSymfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projects
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)
 
Symfony Nano Framework
Symfony Nano FrameworkSymfony Nano Framework
Symfony Nano Framework
 
Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 
A Glymse of Symfony 2
A Glymse of Symfony 2A Glymse of Symfony 2
A Glymse of Symfony 2
 
Symfony 4 & Flex news
Symfony 4 & Flex newsSymfony 4 & Flex news
Symfony 4 & Flex news
 
Sf sf v5
Sf sf v5Sf sf v5
Sf sf v5
 
Nice performance using Sf2 cache wrapping Sf1 application - Paris
Nice performance using Sf2 cache wrapping Sf1 application - ParisNice performance using Sf2 cache wrapping Sf1 application - Paris
Nice performance using Sf2 cache wrapping Sf1 application - Paris
 
An introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersAn introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developers
 
Welcome to the Symfony2 World - FOSDEM 2013
 Welcome to the Symfony2 World - FOSDEM 2013 Welcome to the Symfony2 World - FOSDEM 2013
Welcome to the Symfony2 World - FOSDEM 2013
 
Nice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 applicationNice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 application
 
Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...
Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...
Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and...
 
Symfony
SymfonySymfony
Symfony
 

Dernier

Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 

Dernier (20)

Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 

Symfony Live 09 Symfony 2

  • 1. Symfony 2 Fabien Potencier Symfony 2 | Fabien Potencier
  • 2. Who am I? •  Founder of Sensio – Web Agency (France and USA) – Since 1998 – 70 people – Open-Source Specialists – Big corporate customers – Consulting, training, development, web design, … – Main sponsor of symfony and Doctrine •  Creator and lead developer of symfony Symfony 2 | Fabien Potencier
  • 3. How many of you have used symfony? 1.0? 1.1? 1.2? Symfony 2 | Fabien Potencier
  • 4. 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, … Symfony 2 | Fabien Potencier
  • 5. symfony 1.2 – November 2008 •  Decoupled but cohesive components: the symfony platform –  Forms, Routing, Cache, YAML, ORMs, … •  Controller still based on Mojavi –  View, Filter Chain, … Symfony 2 | Fabien Potencier
  • 6. Roadmap •  1.0 – January 2007 •  1.1 – June 2008 •  1.2 – November 2008 •  1.3 – November 2009 •  Version 2.0 … •  1.4 – Last 1.X version – same as 1.3 but with all deprecated features removed Symfony 2 | Fabien Potencier
  • 7. symfony platform >= 1.1 2.0 sfRequest sfRouting sfLogger sfI18N sfUser sfResponse sfYAML sfDatabase sfForm sfEventDispatcher sfStorage sfCache sfOutputEscaper sfValidator sfWidget sfCoreAutoload platform Symfony 2 | Fabien Potencier
  • 8. Symfony Components •  Standalone components •  Packaged individually •  Upcoming dedicated website –  http://components.symfony-project.org/ •  Dedicated section for each component •  Dedicated documentation •  Dedicated Subversion repository –  http://svn.symfony-project.com/components/ •  Git mirror –  http://github.com/fabpot •  Already published components: –  YAML, Dependency Injection, Event Dispatcher Symfony 2 | Fabien Potencier
  • 9. Symfony 2 is an evolution of symfony 1 •  Same Symfony platform / components •  Different controller implementation •  Oh! Symfony now takes a capital S!!! Symfony 2 | Fabien Potencier
  • 10. Symfony 2 main goals Flexibility Fast Smart Symfony 2 | Fabien Potencier
  • 11. Symfony 2: New components Dependency Injection Container Templating Framework Controller Handling Symfony 2 | Fabien Potencier
  • 12. Symfony 2 •  Not yet available as a full-stack MVC framework •  Some components have already been merged into Symfony 1 –  Event Dispatcher –  Form Framework •  Other new components will soon be released as standalone components: –  Controller Handling –  Templating Framework –  Dependency Injection Container (done) Symfony 2 | Fabien Potencier
  • 13. symfony 1: Not fast enough? Symfony 2 | Fabien Potencier
  • 14. symfony 1 is one of the slowest framework when you test it against a simple Hello World application Symfony 2 | Fabien Potencier
  • 15. 1644& 1544& !"#$%&!'!& 1344& 1144& 1444& ;44& x 19.5 :44& 944& 844& Hello World 744& 644& Benchmark 544& 344& ()"#*& x 2.3 144& +,& -./0)%.&123& 4& based on numbers from http://paul-m-jones.com/?p=315 Symfony 2 | Fabien Potencier
  • 16. Conclusion? Symfony 2 | Fabien Potencier
  • 17. Don’t use symfony for your next « Hello World » website Use PHP ;) Symfony 2 | Fabien Potencier
  • 18. By the way, the fastest implemention of a Hello World application with PHP: die('Hello World'); Symfony 2 | Fabien Potencier
  • 19. But symfony 1 is probably fast enough for your next website Symfony 2 | Fabien Potencier
  • 20. … anyway, it is fast enough for Yahoo! Yahoo! Bookmarks sf-to.org/bookmarks Yahoo! Answers sf-to.org/answers delicious.com sf-to.org/delicious Symfony 2 | Fabien Potencier
  • 21. … and recently dailymotion.com announced its migration to Symfony sf-to.org/dailymotion Symfony 2 | Fabien Potencier
  • 22. Second most popular video sharing website One of the top 50 websites in the world 42 million unique users in December Symfony 2 | Fabien Potencier
  • 23. …and of course many other smaller websites… Symfony 2 | Fabien Potencier
  • 24. Symfony 2: Faster? Symfony 2 | Fabien Potencier
  • 25. Symfony 2 core is so light and flexible that you can easily customize it to have outstanding performance for a Hello World application Symfony 2 | Fabien Potencier
  • 26. Symfony 2 core is so light and flexible that its raw performance is outstanding Symfony 2 | Fabien Potencier
  • 27. require_once dirname(__FILE__).'/sf20/autoload2/sfCore2Autoload.class.php'; sfCore2Autoload::register(); $app = new HelloApplication(); Hello World $app->run()->send(); class HelloApplication 0 h Symfony 2. { public function __construct() { wit $this->dispatcher = new sfEventDispatcher(); $this->dispatcher->connect('application.load_controller', array($this, 'loadController')); } public function run() { $request = new sfWebRequest($this->dispatcher); $handler = new sfRequestHandler($this->dispatcher); $response = $handler->handle($request); return $response; } public function loadController(sfEvent $event) { $event->setReturnValue(array(array($this, 'hello'), array($this->dispatcher, $event['request']))); return true; } public function hello($dispatcher, $request) { $response = new sfWebResponse($dispatcher); $response->setContent('Hello World'); return $response; } } Symfony 2 | Fabien Potencier
  • 28. 7922& 7822& !"#$%&!'!& Hello World Benchmark ()$*+& 7022& 7722& 7222& >22& =22& <22& ;22& :22& ,-./+%-&012& 922& x 3 x 7 822& 022& 3+"#4& 722& 56& ,-./+%-&710& 2& based on numbers from http://paul-m-jones.com/?p=315 Symfony 2 | Fabien Potencier
  • 29. 7 times faster ?! You won’t have such a difference for real applications as most of the time, the limiting factor is not the framework itself Symfony 2 | Fabien Potencier
  • 30. Twitto ?! Symfony 2 | Fabien Potencier
  • 31. Twitto: The PHP framework that fits in a tweet •  The fastest framework around? •  Uses some PHP 5.3 new features •  It also fits in a slide… require __DIR__.'/c.php'; if (!is_callable($c = @$_GET['c'] ?: function() { echo 'Woah!'; })) throw new Exception('Error'); $c(); rg .o twitto Symfony 2 | Fabien Potencier
  • 32. Don’t use Twitto for your next website It is a joke ;) Symfony 2 | Fabien Potencier
  • 33. 7 times faster ?! •  But raw speed matters because – It demonstrates that the core « kernel » is very light – It allows you to use several Symfony frameworks within a single application with the same behavior but different optimizations: •  One full-stack framework optimized for ease of use (think symfony 1) •  One light framework optimized for speed (think Rails Metal ;)) Symfony 2 | Fabien Potencier
  • 34. symfony platform 2.0 sfRequestHandler sfRequest sfRouting sfLogger sfI18N sfUser sfTemplate sfResponse sfValidator sfForm sfWidget sfCache sfDatabase sfStorage sfYAML sfOutputEscaper sfServiceContainer sfEventDispatcher sfCoreAutoload platform Symfony 2 | Fabien Potencier
  • 35. Symfony 2 kernel: The Request Handler Symfony 2 | Fabien Potencier
  • 36. Symfony 2 secret weapon: The Request Handler Symfony 2 | Fabien Potencier
  • 37. The Request Handler •  The backbone of Symfony 2 controller implementation •  Class to build web frameworks, not only MVC ones •  Based on a simple assumption: – The input is a request object – The output is a response object •  The request object can be anything you want •  The response object must implement a send() method Symfony 2 | Fabien Potencier
  • 38. The Request Handler $handler = new sfRequestHandler($dispatcher); $request = new sfWebRequest($dispatcher); $response = $handler->handle($request); $response->send(); Symfony 2 | Fabien Potencier
  • 39. The Request Handler •  The sfRequestHandler does several things: – Notify events – Execute a callable (the controller) – Ensure that the Request is converted to a Response object •  The framework is responsible for choosing the controller •  The controller is responsible for the conversion of the Request to a Response Symfony 2 | Fabien Potencier
  • 40. class sfRequestHandler { protected $dispatcher = null; public function __construct(sfEventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function handle($request) { try { return $this->handleRaw($request); } catch (Exception $e) { $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.exception', array('request' => $request, 'exception' => $e))); if ($event->isProcessed()) { sfRequestHandler return $this->filterResponse($event->getReturnValue(), 'An "application.exception" listener returned a non response object.'); } throw $e; } } is less than 100 public function handleRaw($request) { $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.request', array('request' => $request))); if ($event->isProcessed()) { lines of PHP code! return $this->filterResponse($event->getReturnValue(), 'An "application.request" listener returned a non response object.'); } $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.load_controller', array('request' => $request))); if (!$event->isProcessed()) { throw new Exception('Unable to load the controller.'); } list($controller, $arguments) = $event->getReturnValue(); if (!is_callable($controller)) { throw new Exception(sprintf('The controller must be a callable (%s).', var_export($controller, true))); } $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'application.controller', array('request' => $request, 'controller' => &$controller, 'arguments' => &$arguments))); if ($event->isProcessed()) { try { return $this->filterResponse($event->getReturnValue(), 'An "application.controller" listener returned a non response object.'); } catch (Exception $e) { $retval = $event->getReturnValue(); } } else { $retval = call_user_func_array($controller, $arguments); } $event = $this->dispatcher->filter(new sfEvent($this, 'application.view'), $retval); return $this->filterResponse($event->getReturnValue(), sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : (string) $event->getReturnValue())); } protected function filterResponse($response, $message) { if (!is_object($response) || !method_exists($response, 'send')) { throw new RuntimeException($message); } $event = $this->dispatcher->filter(new sfEvent($this, 'application.response'), $response); $response = $event->getReturnValue(); if (!is_object($response) || !method_exists($response, 'send')) { throw new RuntimeException('An "application.response" listener returned a non response object.'); } return $response; } } Symfony 2 | Fabien Potencier
  • 41. Request Handler Events application.request application.load_controller application.controller application.view application.response application.exception Symfony 2 | Fabien Potencier
  • 42. application.response As the very last event notified, a listener can modify the Response object just before it is returned to the user Symfony 2 | Fabien Potencier
  • 43. application.request •  The very firstevent notified •  It can act as a short-circuit event •  If one listener returns a Response object, it stops the processing Symfony 2 | Fabien Potencier
  • 44. application.load_controller •  Only event for which at least one listener must be connected to •  A listener must return – A PHP callable (the controller) – The arguments to pass to the callable Symfony 2 | Fabien Potencier
  • 45. application.view The controller must return a Response object except if a listener can convert the controller return value to a Response Symfony 2 | Fabien Potencier
  • 46. application.exception The request handler catches all exceptions and give a chance to listeners to return a Response object Symfony 2 | Fabien Potencier
  • 47. Request Handler •  Several listeners can be attached to a single event •  Listeners are called in turn sfEventDispatcher load_controller controller response request view exception request sfRequestHandler response Symfony 2 | Fabien Potencier
  • 48. require_once dirname(__FILE__).'/sf20/autoload2/sfCore2Autoload.class.php'; sfCore2Autoload::register(); $app = new HelloApplication(); $app->run()->send(); class HelloApplication { public function __construct() { $this->dispatcher = new sfEventDispatcher(); Hello World $this->dispatcher->connect('application.load_controller', array($this, 'loadController')); } nts fony Compone public function run() { $request = new sfWebRequest($this->dispatcher); with Sym $handler = new sfRequestHandler($this->dispatcher); $response = $handler->handle($request); return $response; } public function loadController(sfEvent $event) { $event->setReturnValue(array(array($this, 'hello'), array($this->dispatcher, $event['request']))); return true; } public function hello($dispatcher, $request) { $response = new sfWebResponse($dispatcher); $response->setContent('Hello World'); return $response; } } Symfony 2 | Fabien Potencier
  • 50. $app = new HelloApplication(); $app->run()->send(); Symfony 2 | Fabien Potencier
  • 51. public function __construct() { $this->dispatcher = new sfEventDispatcher(); $this->dispatcher->connect( 'application.load_controller', array($this, 'loadController') ); } sfEventDispatcher load_controller controller response request view exception request sfRequestHandler response Symfony 2 | Fabien Potencier
  • 52. public function loadController(sfEvent $event) { $event->setReturnValue(array( array($this, 'hello'), array($this->dispatcher, $event['request']) )); return true; } Symfony 2 | Fabien Potencier
  • 53. public function hello($dispatcher, $request) { $response = new sfWebResponse($dispatcher); $response->setContent('Hello World'); return $response; } Symfony 2 | Fabien Potencier
  • 54. public function run() { $request = new sfWebRequest($this->dispatcher); $handler = new sfRequestHandler($this->dispatcher); $response = $handler->handle($request); return $response; } Symfony 2 | Fabien Potencier
  • 55. Case study: dailymotion.com •  The problem: the Dailymotion developers add new features on a nearly everyday basis •  The challenge: Migrate by introducing small doses of Symfony goodness •  The process – Wrap everything with sfRequestHandler by implementing an application.load_controller listener that calls the old code, based on the request – Migrate the mod_rewrite rules to the symfony routing – Add unit and functional tests Symfony 2 | Fabien Potencier
  • 56. Symfony 2: The Templating Framework Symfony 2 | Fabien Potencier
  • 57. New Templating Framework •  4 components – Template Engine – Template Renderers – Template Loaders – Template Storages •  Independant library Symfony 2 | Fabien Potencier
  • 58. require_once '/path/to/sfCore2Autoload.class.php'; sfCore2Autoload::register(); $dispatcher = new sfEventDispatcher(); $loader = new sfTemplateLoaderFilesystem($dispatcher, '/path/to/templates/%s.php'); $t = new sfTemplateEngine($dispatcher, $loader); echo $t->render('index', array('name' => 'Fabien')); Symfony 2 | Fabien Potencier
  • 59. Template Loaders •  No assumption about where and how templates are to be found – Filesystem – Database – Memory – … •  Template names are « logical » names: $loader = new sfTemplateLoaderFilesystem($dispatcher, '/path/to/templates/%s.php'); Symfony 2 | Fabien Potencier
  • 60. Template Renderers •  No assumption about the format of the templates •  Template names are prefixed with the renderer name: –  index == php:index –  user:index $t = new sfTemplateEngine($dispatcher, $loader, array( 'user' => new ProjectTemplateRenderer($dispatcher), 'php' => new sfTemplateRendererPhp($dispatcher), )); Symfony 2 | Fabien Potencier
  • 61. Template Embedding Hello <?php echo $name ?> <?php $this->render('embedded', array('name' => $name)) ?> <?php $this->render('smarty:embedded') ?> Symfony 2 | Fabien Potencier
  • 62. Template Inheritance <?php $this->decorator('layout') ?> Hello <?php echo $name ?> <html> <head> </head> <body> <?php $this->output('content') ?> </body> </html> Symfony 2 | Fabien Potencier
  • 63. Template Slots <html> <head> <title><?php $this->output('title') ?></title> </head> <body> <?php $this->output('content') ?> </body> </html> <?php $this->set('title', 'Hello World! ') ?> <?php $this->start('title') ?> Hello World! <?php $this->stop() ?> Symfony 2 | Fabien Potencier
  • 64. Template Multiple Inheritance A layout can be decorated by another layout Each layout can override slots Symfony 2 | Fabien Potencier
  • 65. Templating: An example Symfony 2 | Fabien Potencier
  • 66. CMS Templating •  Imagine a CMS with the following features: – The CMS comes bundled with default templates – The developer can override default templates for a specific project – The webmaster can override some templates •  The CMS and developer templates are stored on the filesystem and are written with pure PHP code •  The webmaster templates are stored in a database and are written in a simple templating language: Hello {{ name }} Symfony 2 | Fabien Potencier
  • 67. CMS Templating •  The CMS has several built-in sections and pages – Each page is decorated by a layout, depending on the section – Each section layout is decorated by a base layout cms/templates/ project/templates/ base.php base.php articles/ articles/ layout.php layout.php article.php article.php content.php Symfony 2 | Fabien Potencier
  • 68. articles/content.php <h1>{{ title }}</h1> <p> {{ content }} </p> Symfony 2 | Fabien Potencier
  • 69. articles/article.php <?php $this->decorator('articles/layout') ?> <?php $this->set('title', $title) ?> <?php echo $this->render( 'user:articles/content', array('title' => $title, 'content' => $content) ) ?> Symfony 2 | Fabien Potencier
  • 70. articles/layout.php <?php $this->decorator('base') ?> <?php $this->set('title', 'Articles | '.$this->get('title')) ?> <?php $this->start('head') ?> <?php $this->output('head') ?> <link rel="stylesheet" type="text/css" media="all" href="/css/ articles.css" /> <?php $this->stop() ?> <?php $this->output('content') ?> Symfony 2 | Fabien Potencier
  • 71. articles/layout.php <?php $this->decorator('base') ?> <?php $this->set('title', 'Articles | '.$this->get('title')) ?> <?php $this->stylesheets->add('/css/articles.css') ?> <?php $this->output('content') ?> Symfony 2 | Fabien Potencier
  • 72. base.php <html> <head> <title> <?php $this->output('title') ?> </title> <?php $this->output('head') ?> </head> <body> <?php $this->output('content') ?> </body> </html> Symfony 2 | Fabien Potencier
  • 73. Template Renderer $t = new sfTemplateEngine($dispatcher, $loader, array( 'user' => new ProjectTemplateRenderer($dispatcher), 'php' => new sfTemplateRendererPhp($dispatcher), )); Symfony 2 | Fabien Potencier
  • 74. Template Renderer class ProjectTemplateRenderer extends sfTemplateRenderer { public function evaluate($template, array $parameters = array()) { if ($template instanceof sfTemplateStorageFile) { $template = file_get_contents($template); } $this->parameters = $parameters; return preg_replace_callback('/{{s*(.+?)s*}}/', array($this, 'replaceParameters'), $template); } public function replaceParameters($matches) { return isset($this->parameters[$matches[1]]) ? $this->parameters[$matches[1]] : null; } } Symfony 2 | Fabien Potencier
  • 75. Template Loaders $loader = new sfTemplateLoaderFilesystem($dispatcher, array( '/path/to/project/templates/%s.php', '/path/to/cms/templates/%s.php' )); Symfony 2 | Fabien Potencier
  • 76. Template Loader Chain $loader = new sfTemplateLoaderChain($dispatcher, array( new ProjectTemplateLoader( $dispatcher, array('pdo' => $pdo)), new sfTemplateLoaderFilesystem($dispatcher, array( '/path/to/project/templates/%s.php', '/path/to/cms/templates/%s.php' )), )); Symfony 2 | Fabien Potencier
  • 77. Database Template Loader class ProjectTemplateLoader extends sfTemplateLoader { public function load($template) { $stmt = $this->options['pdo']->prepare('SELECT tpl FROM tpl WHERE name = :name'); try { $stmt->execute(array('name' => $template)); if (count($rows = $stmt->fetchAll(PDO::FETCH_NUM))) { return $rows[0][0]; } } catch (PDOException $e) { } return false; } } Symfony 2 | Fabien Potencier
  • 78. Database Template Loader $pdo = new PDO('sqlite::memory:'); $pdo->exec('CREATE TABLE tpl (name, tpl)'); $pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }} {{ name }}")'); Symfony 2 | Fabien Potencier
  • 79. Template Loader Cache $loader = new sfTemplateLoaderCache( $dispatcher, $loader, new sfFileCache(array('dir' => 'path/to/cache')) ); Symfony 2 | Fabien Potencier
  • 80. $pdo = new PDO('sqlite::memory:'); $pdo->exec('CREATE TABLE tpl (name, tpl)'); $pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }} {{ name }}")'); $loader = new sfTemplateLoaderCache( $dispatcher, new sfTemplateLoaderChain($dispatcher, array( new ProjectTemplateLoader($dispatcher, array('pdo' => $pdo)), new sfTemplateLoaderFilesystem($dispatcher, array( '/path/to/project/templates/%s.php', '/path/to/cms/templates/%s.php' )), )), new sfFileCache(array('dir' => 'path/to/cache')) ); $t = new sfTemplateEngine($dispatcher, $loader, array( 'user' => new ProjectTemplateRenderer($dispatcher) )); $t->render('articles/article', array('title' => 'Title', 'content' => 'Lorem...')); Symfony 2 | Fabien Potencier
  • 81. Symfony 2: Dependency Injection Container Symfony 2 | Fabien Potencier
  • 82. « Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. » h"p://www.picocontainer.org/injec2on.html  Symfony 2 | Fabien Potencier
  • 83. The Symfony 2 dependency injection container replaces several symfony 1 concepts into one integrated system: – sfContext – sfConfiguration – sfConfig – factories.yml – settings.yml / logging.yml / i18n.yml Symfony 2 | Fabien Potencier
  • 84. DI Hello World example class Message { public function __construct(OutputInterface $output, array $options) { $this->output = $output; $this->options = array_merge(array('with_newline' => false), $options); } public function say($msg) { $this->output->render($msg.($this->options['with_newline'] ? "n" : '')); } } Symfony 2 | Fabien Potencier
  • 85. DI Hello World example interface OutputInterface { public function render($msg); } class Output implements OutputInterface { public function render($msg) { echo $msg; } } class FancyOutput implements OutputInterface { public function render($msg) { echo sprintf("033[33m%s033[0m", $msg); } } Symfony 2 | Fabien Potencier
  • 86. DI Hello World example $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World'); Symfony 2 | Fabien Potencier
  • 87. A DI container facilitates objects description and object relationships, configures and instantiates objects Symfony 2 | Fabien Potencier
  • 88. DI Container Hello World example $container = new sfServiceContainerBuilder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new sfServiceReference('output'), array('with_newline' => true))) ; $container->message->say('Hello World!'); Symfony 2 | Fabien Potencier
  • 89. $message = $container->message; Get the configuration for the message service The Message constructor must be given an output service Get the output object from the container Create a Message object by passing the constructor arguments Symfony 2 | Fabien Potencier
  • 90. $message = $container->message; is roughly equivalent to $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true));! Symfony 2 | Fabien Potencier
  • 91. $container = new sfServiceContainerBuilder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new sfServiceReference('output'), array('with_newline' => true))) ; PHP $container->message->say('Hello World!'); <container> <services> XML <service id="output" class="FancyOutput" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument type="collection"> <argument key="with_newline">true</argument> </argument> </service> </services> </container> $container = new sfServiceContainerBuilder(); $loader = new sfServiceLoaderFileXml($container); $loader->load('services.xml'); Symfony 2 | Fabien Potencier
  • 92. $container = new sfServiceContainerBuilder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new sfServiceReference('output'), array('with_newline' => true))) ; PHP $container->message->say('Hello World!'); services: output: { class: FancyOutput } YAML message: class: Message arguments: - @output - { with_newline: true } $container = new sfServiceContainerBuilder(); $loader = new sfServiceLoaderFileYaml($container); $loader->load('services.yml'); Symfony 2 | Fabien Potencier
  • 93. <container> <parameters> <parameter key="output.class">FancyOutput</parameter> <parameter key="message.options" type="collection"> <parameter key="with_newline">true</parameter> </parameter> </parameters> <services> <service id="output" class="%output.class%" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument>%message.options%</argument> </service> </services> </container> $container = new sfServiceContainerBuilder(); $loader = new sfServiceLoaderFileXml($container); $loader->load('services.xml'); Symfony 2 | Fabien Potencier
  • 94. <container> <imports> <import resource="config.xml" /> </imports> <services> <service id="output" class="%output.class%" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument>%message.options%</argument> </service> </services> </container> <container> <parameters> <parameter key="output.class">FancyOutput</parameter> <parameter key="message.options" type="collection"> <parameter key="with_newline">true</parameter> </parameter> </parameters> </container> $container = new sfServiceContainerBuilder(); $loader = new sfServiceLoaderFileXml($container); $loader->load('services.xml'); 2 | Fabien Potencier Symfony
  • 95. <services> <import resource="config.yml" class="sfServiceLoaderFileYaml" /> <service id="output" class="%output.class%" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument>%message.options%</argument> </service> </services> parameters: output.class: FancyOutput message.options: { with_newline: true } $container = new sfServiceContainerBuilder(); $loader = new sfServiceLoaderFileXml($container); $loader->load('services.xml'); Symfony 2 | Fabien Potencier
  • 96. $pdo = new PDO('sqlite::memory:'); $pdo->exec('CREATE TABLE tpl (name, tpl)'); $pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }} {{ name }}")'); $loader = new sfTemplateLoaderCache( $dispatcher, new sfTemplateLoaderChain($dispatcher, array( new ProjectTemplateLoader($dispatcher, array('pdo' => $pdo)), new sfTemplateLoaderFilesystem($dispatcher, array( '/path/to/project/templates/%s.php', '/path/to/cms/templates/%s.php' )), )), new sfFileCache(array('dir' => 'path/to/cache')) ); $t = new sfTemplateEngine($dispatcher, $loader, array( 'user' => new ProjectTemplateRenderer($dispatcher) )); $t->render('articles/article', array('title' => 'Title', 'content' => 'Lorem...')); Symfony 2 | Fabien Potencier
  • 97. $pdo = new PDO('sqlite::memory:'); <service id="pdo" class="PDO"> <argument>sqlite::memory:</argument> </service> Symfony 2 | Fabien Potencier
  • 98. $container = new sfServiceContainerBuilder(); $loader = new sfServiceLoaderFileXml($container); $loader->load('cms.xml'); $pdo->exec('CREATE TABLE tpl (name, tpl)'); $pdo->exec('INSERT INTO tpl (name, tpl) VALUES ("articles/content", "{{ title }} {{ name }}")'); echo $container->template->render('articles/article', array('title' => 'Title', 'content' => 'Lorem...')); Symfony 2 | Fabien Potencier
  • 99. <container> <imports> <import resource="config.yml" class="sfServiceLoaderFileYaml" /> <import resource="template_loader.xml" /> </imports> <services> <service id="event_dispatcher" class="sfEventDispatcher" /> <service id="pdo" class="PDO"> <argument>sqlite::memory:</argument> </service> <service id="template_renderer" class="ProjectTemplateRenderer" lazy="true"> <argument type="service" id="event_dispatcher" /> </service> <service id="template" class="sfTemplateEngine" lazy="true"> <argument type="service" id="event_dispatcher" /> <argument type="service" id="template_loader" /> <argument type="collection"> <argument type="service" key="user" id="template_renderer" /> </argument> </service> </services> </container> Symfony 2 | Fabien Potencier
  • 100. <services> <service id="template_loader_project" class="ProjectTemplateLoader"> <argument type="service" id="event_dispatcher" /> <argument type="collection"><argument type="service" key="pdo" id="pdo" /></argument> </service> <service id="template_loader_filesystem" class="sfTemplateLoaderFilesystem"> <argument type="service" id="event_dispatcher" /> <argument>%template.filesystem_pattern%</argument> </service> <service id="template_loader_chain" class="sfTemplateLoaderChain"> <argument type="service" id="event_dispatcher" /> <argument type="collection"> <argument type="service" id="template_loader_project" /> <argument type="service" id="template_loader_filesystem" /> </argument> </service> <service id="template_loader_cache" class="sfFileCache"> <argument type="collection"><argument key="cache_dir">%application.dir%/cache</argument></argument> </service> <service id="template_loader" class="sfTemplateLoaderCache" lazy="true"> <argument type="service" id="event_dispatcher" /> <argument type="service" id="template_loader_chain" /> <argument type="service" id="template_cache" /> </service> </services> Symfony 2 | Fabien Potencier
  • 101. <services> <service id="template_loader" class="sfTemplateLoaderCache" lazy="true"> <argument type="service" id="event_dispatcher" /> <argument type="service"> <service class="sfTemplateLoaderChain"> <argument type="service" id="event_dispatcher" /> <argument type="collection"> <argument type="service"> <service class="ProjectTemplateLoader"> <argument type="service" id="event_dispatcher" /> <argument type="collection"><argument type="service" key="pdo" id="pdo" /></argument> </service> </argument> <argument type="service"> <service class="sfTemplateLoaderFilesystem"> <argument type="service" id="event_dispatcher" /> <argument>%template.filesystem_patterns%</argument> </service> </argument> </argument> </service> </argument> <argument type="service"> <service class="sfFileCache"> <argument type="collection"><argument key="cache_dir">%application.dir%/cache</argument></argument> </service> </argument> </service> </services> Symfony 2 | Fabien Potencier
  • 102. Symfony 2 | Fabien Potencier
  • 103. Questions? Symfony 2 | Fabien Potencier
  • 104. Sensio S.A. 92-98, boulevardVictor 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/ Symfony 2 | Fabien Potencier