SlideShare une entreprise Scribd logo
1  sur  48
Télécharger pour lire hors ligne
symfony
                         symfony as a platform


                                  Fabien Potencier
                         http://www.symfony-project.com/
                            http://www.sensiolabs.com/



Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
symfony 1.1
  • A lot of internal refactoring… really a lot
  • Some new features… but not a lot
         – Tasks are now classes
         – More cache classes: APC, Eaccelerator, File,
           Memcache, SQLite, XCache
         – Configurable Routing: Pattern, PathInfo
         – … and some more
  • Yes, we will have a new form/validation system…
    but we still need some internal refactoring

Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Singletons
                         1.0                                            1.1
                    sfConfigCache                                  sfConfigCache
                    sfContext                                      sfContext
                    sfRouting
                    sfWebDebug
                    sfI18N
                    sfLogger
                                                                        Remove
                                                                       Singletons

Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Why?
  // somewhere in the backend application
  $frontendRouting = sfContext::getInstance('frontend')->getRouting();

  $url = $frontendRouting->generate('article', array('id' => 1));



  // somewhere in a functional test
  $fabien = new sfTestBrowser('frontend');
  $thomas = new sfTestBrowser('frontend');

  $fabien->get('/talk_to/thomas/say/Hello');
  $thomas->get('/last_messages');
  $thomas->checkResponseElement('li', '/Hello/i');


                    Don’t try this at home… it won’t work… yet
Symfony Camp 2007        www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
symfony 1.0 Dependencies
                    sfView

                                               sfResponse
                                                                                        sfContext

                              sfI18N                     sfRequest
                                                                                         sfLogger

          sfStorage              sfUser

                                                             sfRouting                     Cleanup
                    dependency
                                                                                         Dependencies
  singleton

Symfony Camp 2007        www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
symfony 1.1 Dependencies
                                      sfRequest                    sfView
                                                                                     sfResponse
                      sfI18N
                                             sfEventDispatcher


                      sfUser                                                           sfRouting

   sfStorage                         sfLogger                   sfContext

                                                                                           Cleanup
                    dependency
                                                                                         Dependencies
  singleton

Symfony Camp 2007        www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
sfEventDispatcher
  • Based on Cocoa Notification Center
  // sfUser
  $event = new sfEvent($this, 'user.change_culture', array('culture' => $culture));
  $dispatcher->notify($event);

  // sfI18N
  $callback = array($this, 'listenToChangeCultureEvent');
  $dispatcher->connect('user.change_culture', $callback);



  • sfI18N and sfUser are decoupled
  • « Anybody » can listen to any event
  • You can notify existing events or create new ones

Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Why?


     Let’s talk about symfony 2.0…




Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
The Web Workflow

                The User asks a Resource in a Browser

          The Browser sends a Request to the Server

                    The Server sends back a Response

     The Browser displays the Resource to the User

Symfony Camp 2007      www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_00.php?name=Fabien
  session_start();

  if (isset($_GET['name']))
  {
    $name = $_GET['name'];
  }
  else if (isset($_SESSION['name']))
  {
    $name = $_SESSION['name'];
  }
  else
  {
    $name = 'World';
  }

  $_SESSION['name'] = $name;

  echo 'Hello '.$name;

      User > Resource > Request > Response
                        Request   Response
Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
sfWebRequest
                           PHP                                                              Object
  $_SERVER[‘REQUEST_METHOD’]                                                    >getMethod()
  $_GET[‘name’]                                                                 >getParameter(‘name’)

  get_magic_quotes_gpc() ?
   stripslashes($_COOKIE[$name]) : $_COOKIE[$name];
                                                                                >getCookie(‘name’)

  (
      isset($_SERVER['HTTPS'])
      && (
        strtolower($_SERVER ['HTTPS']) == 'on’
          ||
                                                                                >isSecure()
        strtolower($_SERVER ['HTTPS']) == 1)
        )
      || (
        isset($_SERVER ['HTTP_X_FORWARDED_PROTO'])
          &&
        strtolower($_SERVER ['HTTP_X_FORWARDED_PROTO']) == 'https')
        )                                                                               Mock sfWebRequest
  )
                                     Abstract                                                  to test
                                    Parameters                                          without a HTTP layer
                                     Headers
Symfony Camp 2007               www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_01.php?name=Fabien

  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEventDispatcher();
  $request = new sfWebRequest($dispatcher);

  session_start();

  if ($request->hasParameter('name'))
  {
    $name = $request->getParameter('name');
  }
  else if (isset($_SESSION['name']))
  {
    $name = $_SESSION['name'];
  }
  else
  {
    $name = 'World';
  }

  $_SESSION['name'] = $name;

  echo 'Hello '.$name;


      User > Resource > Request > Response
                        Request   Response
Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
sfWebResponse
                    PHP                                                            Object
  echo ‘Hello World!’                                                 >setContent(‘Hello World’)

  header(‘HTTP/1.0 404 Not Found’)                                    >setStatusCode(404)

  setcookie(‘name’, ‘value’)                                          >setCookie(‘name’, ‘value’)




                                                                              Mock sfWebResponse
                             Abstract
                                                                                     to test
                             Headers
                                                                              without a HTTP layer
                             Cookies

Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com    www.sensiolabs.com
http://localhost/step_02.php?name=Fabien
  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEventDispatcher();
  $request = new sfWebRequest($dispatcher);
  session_start();

  if (!$name = $request->getParameter('name'))
  {
    if (isset($_SESSION['name']))
    {
      $name = $_SESSION['name'];
    }
    else
    {
      $name = 'World';
    }
  }

  $_SESSION['name'] = $name;

  $response = new sfWebResponse($dispatcher);
  $response->setContent('Hello '.$name);
  $response->send();


      User > Resource > Request > Response
                        Request   Response
Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
sfUser / sfStorage
                    PHP                                                           Object
  $_SESSION[‘name’] = ‘value’                                         >setAttribute(‘name’, ‘value’)

                                                                      >setCulture(‘fr’)

                                                                      >setAuthenticated(true)

                                                                      Native session storage +
                                                                      MySQL, PostgreSQL, PDO, …




                                                                                  Mock sfUser
                            Abstract
                                                                                     to test
                          $_SESSION
                                                                              without a HTTP layer
                          Add features

Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_03.php?name=Fabien
  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEventDispatcher();
  $storage = new sfSessionStorage();
  $user = new sfUser($dispatcher, $storage);
  $request = new sfWebRequest($dispatcher);

  if (!$name = $request->getParameter('name'))
  {
    if (!$name = $user->getAttribute('name'))
    {
      $name = 'World';
    }
  }

  $user->setAttribute('name', $name);

  $response = new sfWebResponse($dispatcher);
  $response->setContent('Hello '.$name);
  $response->send();


      User > Resource > Request > Response
                        Request   Response
Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_04.php?name=Fabien

  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEventDispatcher();
  $storage = new sfSessionStorage();
  $user = new sfUser($dispatcher, $storage);
  $request = new sfWebRequest($dispatcher);

  $name = $request->getParameter('name', $user->getAttribute('name', 'World')));


  $user->setAttribute('name', $name);

  $response = new sfWebResponse($dispatcher);
  $response->setContent('Hello '.$name);
  $response->send();




      User > Resource > Request > Response
                        Request   Response
Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
sfRouting
  • Clean URLs <> Resources
  • Parses PATH_INFO to inject parameters in the
    sfRequest object
  • Several strategies: PathInfo, Pattern
  • Decouples Request and Controller




Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_05.php/hello/Fabien

  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEventDispatcher();
  $storage = new sfSessionStorage();
  $user = new sfUser($dispatcher, $storage);
  $routing = new sfPatternRouting($dispatcher);
  $routing->connect('hello', '/hello/:name');
  $request = new sfWebRequest($dispatcher);

  $name = $request->getParameter('name', $user->getAttribute('name', 'World')));


  $user->setAttribute('name', $name);

  $response = new sfWebResponse($dispatcher);
  $response->setContent('Hello '.$name);
  $response->send();




      User > Resource > Request > Response
                        Request   Response
Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
The Web Workflow

                The User asks a Resource in a Browser

          The Browser sends a Request to the Server

                    The Server sends back a Response

     The Browser displays the Resource to the User

Symfony Camp 2007      www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
symfony 2.0 philosophy



               Request
                                               ?                                 Response




  symfony gives                                                              symfony wants
  you a sfRequest                                                            a sfResponse
Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com    www.sensiolabs.com
Let’s create symfony 2.0…



Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
The Controller
  • The dispatching logic is the same for every
    resource
  • The business logic depends on the resource and
    is managed by the controller

  • The controller responsability is to « convert » the
    request to the response



Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_06.php/hello/Fabien
  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEventDispatcher();
  $storage = new sfSessionStorage();
  $user = new sfUser($dispatcher, $storage);
  $routing = new sfPatternRouting($dispatcher);
  $routing->connect('hello', '/hello/:name',
    array('controller' => 'hello', 'action' => 'index'));
  $request = new sfWebRequest($dispatcher);

  $class = $request->getParameter('controller').'Controller';
  $method = $request->getParameter('action').'Action';
  $controller = new $class();

  $response = $controller->$method($dispatcher, $request, $user);

  $response->send();




Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_06.php/hello/Fabien
  class helloController
  {
    function indexAction($dispatcher, $request, $user)
    {
          $name = $request->getParameter('name', $user->getAttribute('name', 'World')));


          $user->setAttribute('name', $name);

          $response = new sfWebResponse($dispatcher);
          $response->setContent('Hello '.$name);

          return $response;
      }
  }




Symfony Camp 2007       www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
The RequestHandler
  • Handles the dispatching of the request
  • Calls the Controller
  • Has the responsability to return a sfResponse




Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_07.php/hello/Fabien

  require dirname(__FILE__).'/../symfony_platform.php';
  require dirname(__FILE__).'/step_07_framework.php';

  $dispatcher = new sfEventDispatcher();
  $storage = new sfSessionStorage();
  $user = new sfUser($dispatcher, $storage);
  $routing = new sfPatternRouting($dispatcher);
  $routing->connect('hello', '/hello/:name',
    array('controller' => 'hello', 'action' => 'index'));
  $request = new sfWebRequest($dispatcher);

  $response = RequestHandler::handle($dispatcher, $request, $user);

  $response->send();




Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_07.php/hello/Fabien
  class RequestHandler
  {
    function handle($dispatcher, $request, $user)
    {
      $class = $request->getParameter('controller').'Controller';
      $method = $request->getParameter('action').'Action';

          $controller = new $class();
          try
          {
            $response = $controller->$method($dispatcher, $request, $user);
          }
          catch (Exception $e)
          {
            $response = new sfWebResponse($dispatcher);
            $response->setStatusCode(500);
              $response->setContent(sprintf('An error occurred: %s', $e->getMessage()));
          }

          return $response;
      }
  }

Symfony Camp 2007         www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
I WANT a sfResponse


Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_08.php/hello/Fabien
  try
  {
    if (!class_exists($class))
    {
      throw new Exception('Controller class does not exist');
    }

     $controller = new $class();

     if (!method_exists($class, $method))
     {
       throw new Exception('Controller method does not exist');
     }

     $response = $controller->$method($dispatcher, $request, $user);

     if (!is_object($response) || !$response instanceof sfResponse)
     {
       throw new Exception('Controller must return a sfResponse object');
     }
  }
  catch (Exception $e)
  {
    $response = new sfWebResponse($dispatcher);
    $response->setStatusCode(500);
    $response->setContent(sprintf('An error occurred: %s', $e->getMessage()));
  }
Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
The Application
  $response = $controller->$method($dispatcher, $request, $user);




  • I need a container for my application objects
         –   The dispatcher
         –   The user
         –   The routing
         –   The I18N
         –   The Database
         –   …
  • These objects are specific to my Application and does not
    depend on the request
Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_09.php/hello/Fabien
  abstract class Application
  {
    public $dispatcher, $user, $routing;

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

          $this->configure();
      }

      abstract function configure();

      function handle($request)
      {
        return RequestHandler::handle($this, $request);
      }
  }




Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_09.php/hello/Fabien
  class HelloApplication extends Application
  {
    function configure()
    {
      $storage = new sfSessionStorage();
      $this->user = new sfUser($this->dispatcher, $storage);

          $this->routing = new sfPatternRouting($this->dispatcher);
          $this->routing->connect('hello', '/hello/:name',
             array('controller' => 'hello', 'action' => 'index'));
      }
  }

  $dispatcher = new sfEventDispatcher();
  $request = new sfWebRequest($dispatcher);

  $application = new HelloApplication($dispatcher);
  $response = $application->handle($request);

  $response->send();




Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Sensible defaults
  • Most of the time
         – The dispatcher is a sfEventDispatcher
         – The request is a sfWebRequest object
         – The controller must create a sfWebResponse object


  • Let’s introduce a new Controller abstract class
  • Modify the Application to takes defaults



Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_10.php/hello/Fabien
  class Controller
  {
    public $application;

      function __construct($application)
      {
        $this->application = $application;
      }

      function renderToResponse($content)
      {
        $response = new sfWebResponse($this->application->dispatcher);
        $response->setContent($content);

          return $response;
      }
  }

  class helloController extends Controller
  {
    function indexAction($request)
    {
          $name = $request->getParameter('name', $this->application->user->getAttribute('name', 'World')));


          $this->application->user->setAttribute('name', $name);

          return $this->renderToResponse('Hello '.$name);
      }
  }
Symfony Camp 2007             www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_10.php/hello/Fabien
  abstract class Application
  {
    function __construct($dispatcher = null)
    {
          $this->dispatcher = is_null($dispatcher) ? new sfEventDispatcher() : $dispatcher;


          $this->configure();
      }

      function handle($request = null)
      {
          $request = is_null($request) ? new sfWebRequest($this->dispatcher) : $request;


          return RequestHandler::handle($this, $request);
      }
  }




Symfony Camp 2007       www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Let’s have a look at the code




Symfony Camp 2007      www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
The directory structure
  • A directory for each application
         – An application class
         – A controller directory
         – A template directory




Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_11.php/hello/Fabien
  class HelloApplication extends Application
  {
    function configure()
    {
      $storage = new sfSessionStorage();
      $this->user = new sfUser($this->dispatcher, $storage);

          $this->routing = new sfPatternRouting($this->dispatcher);
          $this->routing->connect('hello', '/hello/:name',
             array('controller' => 'hello', 'action' => 'index'));

          $this->template = new Template();

          $this->root = dirname(__FILE__);
      }
  }




Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_11.php/hello/Fabien
  class Template
  {
    function render($template, $parameters = array())
    {
      extract($parameters);

          ob_start();
          require $template;

          return ob_get_clean();
      }
  }

  class Controller
  {
    …
    function renderToResponse($templateName, $parameters = array())
    {
      $content = $this->application->template->render($templateName, $parameters);

          $response = new sfWebResponse($this->application->dispatcher);
          $response->setContent($content);

          return $response;
      }
  }


Symfony Camp 2007         www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Customization
  • Add some events in the RequestHandler
         – application.request
         – application.controller
         – application.response
         – application.exception


  • They can return a sfResponse and stop the
    RequestHandler flow


Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
http://localhost/step_12.php/hello/Fabien



  $parameters = array('request' => $request);

  $event = new sfEvent($application, 'application.request', $parameters);

  $application->dispatcher->notifyUntil($event);

  if ($event->isProcessed())
  {
    return $event->getReturnValue();
  }




Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
What for?
  • Page caching
         – application.request: If I have the page in cache,
           unserialize the response from the cache and returns it
         – application.response : Serialize the response to the
           cache
  • Security
         – application.controller: Check security and change the
           controller if needed



Symfony Camp 2007   www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
class HelloApplication extends Application
  {
    function configure()
    {
      $storage = new sfSessionStorage();
      $this->user = new sfUser($this->dispatcher, $storage);

          $this->routing = new sfPatternRouting($this->dispatcher);
          $this->routing->connect('hello', '/hello/:name',
             array('controller' => 'hello', 'action' => 'index'));

          $this->template = new Template();

          $this->root = dirname(__FILE__);

          CacheListener::register($dispatcher, $this->root.'/cache/cache.db');
      }
  }




Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
class CacheListener
  {
    public $cache, $key;

      static function register($dispatcher, $database)
      {
          $listener = new __CLASS__();
          $listener->cache = new sfSQLiteCache(array('database' => $database));
          $dispatcher->connect('application.request', array($listener, 'listenToRequest'));
          $dispatcher->connect('application.response', array($listener, 'listenToResponse'));
      }

      function listenToRequest($event)
      {
        $this->key = md5($event->getParameter('request')->getPathInfo());

          if ($cache = $this->cache->get($this->key))
          {
              $this->setProcessed(true);
              $this->setReturnValue(unserialize($cache));
          }
      }

      function listenToResponse($event, $response)
      {
        $this->cache->set($this->key, serialize($response);

          return $response;
      }
  }


Symfony Camp 2007             www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Next symfony Workshops


   En français : Paris, France - Dec 05, 2007

     In English : Paris, France - Feb 13, 2008

               More info on www.sensiolabs.com

Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
Join Us
  • Sensio Labs is recruiting in France
         – project managers
         – web developers
  • You have a passion for the web?
         – Web Developer : You have a minimum of 3 years experience in web
           development with Open-Source projects and you wish to participate to
           development of Web 2.0 sites using the best frameworks available.
         – Project Manager : You have more than 5 years experience as a developer
           and/or a project manager and you want to manage complex Web projects for
           prestigious clients.




Symfony Camp 2007     www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com
SENSIO S.A.
                                  26, rue Salomon de Rothschild
                                      92 286 Suresnes Cedex
                                             FRANCE
                                         Tél. : +33 1 40 99 80 80
                                         Fax : +33 1 40 99 83 34

                                              Contact
                                         Fabien Potencier
                                   fabien.potencier@sensio.com




        http://www.sensiolabs.com/                                  http://www.symfony-project.com/
Symfony Camp 2007    www.symfony-project.com   fabien.potencier@sensio.com   www.sensiolabs.com

Contenu connexe

Tendances

Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoMasahiro Nagano
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHPWim Godden
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021Ayesh Karunaratne
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?Radek Benkel
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Riza Fahmi
 
async/await Revisited
async/await Revisitedasync/await Revisited
async/await RevisitedRiza Fahmi
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Nikita Popov
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0Henrique Moody
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Fwdays
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Nikita Popov
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojobpmedley
 

Tendances (20)

Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6
 
async/await Revisited
async/await Revisitedasync/await Revisited
async/await Revisited
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 

En vedette

What Symfony Has To Do With My Garage - Home Automation With PHP
What Symfony Has To Do With My Garage - Home Automation With PHPWhat Symfony Has To Do With My Garage - Home Automation With PHP
What Symfony Has To Do With My Garage - Home Automation With PHPJan Unger
 
Decoupling Content Management with Create.js and PHPCR
Decoupling Content Management with Create.js and PHPCRDecoupling Content Management with Create.js and PHPCR
Decoupling Content Management with Create.js and PHPCRHenri Bergius
 
Plugins And Making Your Own
Plugins And Making Your OwnPlugins And Making Your Own
Plugins And Making Your OwnLambert Beekhuis
 
OkAPI meet symfony, symfony meet OkAPI
OkAPI meet symfony, symfony meet OkAPIOkAPI meet symfony, symfony meet OkAPI
OkAPI meet symfony, symfony meet OkAPILukas Smith
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
PHP, Cloud And Microsoft Symfony Live 2010
PHP,  Cloud And  Microsoft    Symfony  Live 2010PHP,  Cloud And  Microsoft    Symfony  Live 2010
PHP, Cloud And Microsoft Symfony Live 2010guest5a7126
 
How to Clear Cache in a Symfony Cross Application
How to Clear Cache in a Symfony Cross ApplicationHow to Clear Cache in a Symfony Cross Application
How to Clear Cache in a Symfony Cross ApplicationMike Taylor
 
Apostrophe
ApostropheApostrophe
Apostrophetompunk
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationJonathan Wage
 
Doctrine in the Real World
Doctrine in the Real WorldDoctrine in the Real World
Doctrine in the Real WorldJonathan Wage
 
Doctrine Php Object Relational Mapper
Doctrine Php Object Relational MapperDoctrine Php Object Relational Mapper
Doctrine Php Object Relational Mapperguesta3af58
 
Implementing a Symfony Based CMS in a Publishing Company
Implementing a Symfony Based CMS in a Publishing CompanyImplementing a Symfony Based CMS in a Publishing Company
Implementing a Symfony Based CMS in a Publishing CompanyMarcos Labad
 

En vedette (20)

What Symfony Has To Do With My Garage - Home Automation With PHP
What Symfony Has To Do With My Garage - Home Automation With PHPWhat Symfony Has To Do With My Garage - Home Automation With PHP
What Symfony Has To Do With My Garage - Home Automation With PHP
 
Decoupling Content Management with Create.js and PHPCR
Decoupling Content Management with Create.js and PHPCRDecoupling Content Management with Create.js and PHPCR
Decoupling Content Management with Create.js and PHPCR
 
Plugins And Making Your Own
Plugins And Making Your OwnPlugins And Making Your Own
Plugins And Making Your Own
 
Debugging With Symfony
Debugging With SymfonyDebugging With Symfony
Debugging With Symfony
 
OkAPI meet symfony, symfony meet OkAPI
OkAPI meet symfony, symfony meet OkAPIOkAPI meet symfony, symfony meet OkAPI
OkAPI meet symfony, symfony meet OkAPI
 
Symfony Internals
Symfony InternalsSymfony Internals
Symfony Internals
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
The new form framework
The new form frameworkThe new form framework
The new form framework
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
PHP, Cloud And Microsoft Symfony Live 2010
PHP,  Cloud And  Microsoft    Symfony  Live 2010PHP,  Cloud And  Microsoft    Symfony  Live 2010
PHP, Cloud And Microsoft Symfony Live 2010
 
Symfony in the Cloud
Symfony in the CloudSymfony in the Cloud
Symfony in the Cloud
 
How to Clear Cache in a Symfony Cross Application
How to Clear Cache in a Symfony Cross ApplicationHow to Clear Cache in a Symfony Cross Application
How to Clear Cache in a Symfony Cross Application
 
Apostrophe
ApostropheApostrophe
Apostrophe
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
 
Doctrine in the Real World
Doctrine in the Real WorldDoctrine in the Real World
Doctrine in the Real World
 
Developing for Developers
Developing for DevelopersDeveloping for Developers
Developing for Developers
 
Doctrine Php Object Relational Mapper
Doctrine Php Object Relational MapperDoctrine Php Object Relational Mapper
Doctrine Php Object Relational Mapper
 
Symfony and eZ Publish
Symfony and eZ PublishSymfony and eZ Publish
Symfony and eZ Publish
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
Implementing a Symfony Based CMS in a Publishing Company
Implementing a Symfony Based CMS in a Publishing CompanyImplementing a Symfony Based CMS in a Publishing Company
Implementing a Symfony Based CMS in a Publishing Company
 

Similaire à Symfony As A Platform (Symfony Camp 2007)

The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Fabien Potencier
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)Péhápkaři
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Kacper Gunia
 
Symfony 2.0
Symfony 2.0Symfony 2.0
Symfony 2.0GrUSP
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
When symfony met promises
When symfony met promises When symfony met promises
When symfony met promises Marc Morera
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Jason Lotito
 
Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Fabien Potencier
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 

Similaire à Symfony As A Platform (Symfony Camp 2007) (20)

The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Symfony 2 (PHP day 2009)
Symfony 2 (PHP day 2009)Symfony 2 (PHP day 2009)
Symfony 2 (PHP day 2009)
 
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Symfony 2.0
Symfony 2.0Symfony 2.0
Symfony 2.0
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
PHP pod mikroskopom
PHP pod mikroskopomPHP pod mikroskopom
PHP pod mikroskopom
 
When symfony met promises
When symfony met promises When symfony met promises
When symfony met promises
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 

Plus de Fabien Potencier

Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Fabien Potencier
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Fabien Potencier
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Fabien Potencier
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien Potencier
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 
Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3Fabien Potencier
 

Plus de Fabien Potencier (20)

Varnish
VarnishVarnish
Varnish
 
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3
 
Playing With PHP 5.3
Playing With PHP 5.3Playing With PHP 5.3
Playing With PHP 5.3
 

Dernier

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
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
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 

Dernier (20)

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
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?
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 

Symfony As A Platform (Symfony Camp 2007)

  • 1. symfony symfony as a platform Fabien Potencier http://www.symfony-project.com/ http://www.sensiolabs.com/ Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 2. symfony 1.1 • A lot of internal refactoring… really a lot • Some new features… but not a lot – Tasks are now classes – More cache classes: APC, Eaccelerator, File, Memcache, SQLite, XCache – Configurable Routing: Pattern, PathInfo – … and some more • Yes, we will have a new form/validation system… but we still need some internal refactoring Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 3. Singletons 1.0 1.1 sfConfigCache sfConfigCache sfContext sfContext sfRouting sfWebDebug sfI18N sfLogger Remove Singletons Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 4. Why? // somewhere in the backend application $frontendRouting = sfContext::getInstance('frontend')->getRouting(); $url = $frontendRouting->generate('article', array('id' => 1)); // somewhere in a functional test $fabien = new sfTestBrowser('frontend'); $thomas = new sfTestBrowser('frontend'); $fabien->get('/talk_to/thomas/say/Hello'); $thomas->get('/last_messages'); $thomas->checkResponseElement('li', '/Hello/i'); Don’t try this at home… it won’t work… yet Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 5. symfony 1.0 Dependencies sfView sfResponse sfContext sfI18N sfRequest sfLogger sfStorage sfUser sfRouting Cleanup dependency Dependencies singleton Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 6. symfony 1.1 Dependencies sfRequest sfView sfResponse sfI18N sfEventDispatcher sfUser sfRouting sfStorage sfLogger sfContext Cleanup dependency Dependencies singleton Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 7. sfEventDispatcher • Based on Cocoa Notification Center // sfUser $event = new sfEvent($this, 'user.change_culture', array('culture' => $culture)); $dispatcher->notify($event); // sfI18N $callback = array($this, 'listenToChangeCultureEvent'); $dispatcher->connect('user.change_culture', $callback); • sfI18N and sfUser are decoupled • « Anybody » can listen to any event • You can notify existing events or create new ones Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 8. Why? Let’s talk about symfony 2.0… Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 9. The Web Workflow The User asks a Resource in a Browser The Browser sends a Request to the Server The Server sends back a Response The Browser displays the Resource to the User Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 10. http://localhost/step_00.php?name=Fabien session_start(); if (isset($_GET['name'])) { $name = $_GET['name']; } else if (isset($_SESSION['name'])) { $name = $_SESSION['name']; } else { $name = 'World'; } $_SESSION['name'] = $name; echo 'Hello '.$name; User > Resource > Request > Response Request Response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 11. sfWebRequest PHP Object $_SERVER[‘REQUEST_METHOD’] >getMethod() $_GET[‘name’] >getParameter(‘name’) get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; >getCookie(‘name’) ( isset($_SERVER['HTTPS']) && ( strtolower($_SERVER ['HTTPS']) == 'on’ || >isSecure() strtolower($_SERVER ['HTTPS']) == 1) ) || ( isset($_SERVER ['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER ['HTTP_X_FORWARDED_PROTO']) == 'https') ) Mock sfWebRequest ) Abstract to test Parameters without a HTTP layer Headers Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 12. http://localhost/step_01.php?name=Fabien require dirname(__FILE__).'/../symfony_platform.php'; $dispatcher = new sfEventDispatcher(); $request = new sfWebRequest($dispatcher); session_start(); if ($request->hasParameter('name')) { $name = $request->getParameter('name'); } else if (isset($_SESSION['name'])) { $name = $_SESSION['name']; } else { $name = 'World'; } $_SESSION['name'] = $name; echo 'Hello '.$name; User > Resource > Request > Response Request Response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 13. sfWebResponse PHP Object echo ‘Hello World!’ >setContent(‘Hello World’) header(‘HTTP/1.0 404 Not Found’) >setStatusCode(404) setcookie(‘name’, ‘value’) >setCookie(‘name’, ‘value’) Mock sfWebResponse Abstract to test Headers without a HTTP layer Cookies Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 14. http://localhost/step_02.php?name=Fabien require dirname(__FILE__).'/../symfony_platform.php'; $dispatcher = new sfEventDispatcher(); $request = new sfWebRequest($dispatcher); session_start(); if (!$name = $request->getParameter('name')) { if (isset($_SESSION['name'])) { $name = $_SESSION['name']; } else { $name = 'World'; } } $_SESSION['name'] = $name; $response = new sfWebResponse($dispatcher); $response->setContent('Hello '.$name); $response->send(); User > Resource > Request > Response Request Response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 15. sfUser / sfStorage PHP Object $_SESSION[‘name’] = ‘value’ >setAttribute(‘name’, ‘value’) >setCulture(‘fr’) >setAuthenticated(true) Native session storage + MySQL, PostgreSQL, PDO, … Mock sfUser Abstract to test $_SESSION without a HTTP layer Add features Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 16. http://localhost/step_03.php?name=Fabien require dirname(__FILE__).'/../symfony_platform.php'; $dispatcher = new sfEventDispatcher(); $storage = new sfSessionStorage(); $user = new sfUser($dispatcher, $storage); $request = new sfWebRequest($dispatcher); if (!$name = $request->getParameter('name')) { if (!$name = $user->getAttribute('name')) { $name = 'World'; } } $user->setAttribute('name', $name); $response = new sfWebResponse($dispatcher); $response->setContent('Hello '.$name); $response->send(); User > Resource > Request > Response Request Response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 17. http://localhost/step_04.php?name=Fabien require dirname(__FILE__).'/../symfony_platform.php'; $dispatcher = new sfEventDispatcher(); $storage = new sfSessionStorage(); $user = new sfUser($dispatcher, $storage); $request = new sfWebRequest($dispatcher); $name = $request->getParameter('name', $user->getAttribute('name', 'World'))); $user->setAttribute('name', $name); $response = new sfWebResponse($dispatcher); $response->setContent('Hello '.$name); $response->send(); User > Resource > Request > Response Request Response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 18. sfRouting • Clean URLs <> Resources • Parses PATH_INFO to inject parameters in the sfRequest object • Several strategies: PathInfo, Pattern • Decouples Request and Controller Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 19. http://localhost/step_05.php/hello/Fabien require dirname(__FILE__).'/../symfony_platform.php'; $dispatcher = new sfEventDispatcher(); $storage = new sfSessionStorage(); $user = new sfUser($dispatcher, $storage); $routing = new sfPatternRouting($dispatcher); $routing->connect('hello', '/hello/:name'); $request = new sfWebRequest($dispatcher); $name = $request->getParameter('name', $user->getAttribute('name', 'World'))); $user->setAttribute('name', $name); $response = new sfWebResponse($dispatcher); $response->setContent('Hello '.$name); $response->send(); User > Resource > Request > Response Request Response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 20. The Web Workflow The User asks a Resource in a Browser The Browser sends a Request to the Server The Server sends back a Response The Browser displays the Resource to the User Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 21. symfony 2.0 philosophy Request ? Response symfony gives symfony wants you a sfRequest a sfResponse Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 22. Let’s create symfony 2.0… Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 23. The Controller • The dispatching logic is the same for every resource • The business logic depends on the resource and is managed by the controller • The controller responsability is to « convert » the request to the response Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 24. http://localhost/step_06.php/hello/Fabien require dirname(__FILE__).'/../symfony_platform.php'; $dispatcher = new sfEventDispatcher(); $storage = new sfSessionStorage(); $user = new sfUser($dispatcher, $storage); $routing = new sfPatternRouting($dispatcher); $routing->connect('hello', '/hello/:name', array('controller' => 'hello', 'action' => 'index')); $request = new sfWebRequest($dispatcher); $class = $request->getParameter('controller').'Controller'; $method = $request->getParameter('action').'Action'; $controller = new $class(); $response = $controller->$method($dispatcher, $request, $user); $response->send(); Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 25. http://localhost/step_06.php/hello/Fabien class helloController { function indexAction($dispatcher, $request, $user) { $name = $request->getParameter('name', $user->getAttribute('name', 'World'))); $user->setAttribute('name', $name); $response = new sfWebResponse($dispatcher); $response->setContent('Hello '.$name); return $response; } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 26. The RequestHandler • Handles the dispatching of the request • Calls the Controller • Has the responsability to return a sfResponse Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 27. http://localhost/step_07.php/hello/Fabien require dirname(__FILE__).'/../symfony_platform.php'; require dirname(__FILE__).'/step_07_framework.php'; $dispatcher = new sfEventDispatcher(); $storage = new sfSessionStorage(); $user = new sfUser($dispatcher, $storage); $routing = new sfPatternRouting($dispatcher); $routing->connect('hello', '/hello/:name', array('controller' => 'hello', 'action' => 'index')); $request = new sfWebRequest($dispatcher); $response = RequestHandler::handle($dispatcher, $request, $user); $response->send(); Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 28. http://localhost/step_07.php/hello/Fabien class RequestHandler { function handle($dispatcher, $request, $user) { $class = $request->getParameter('controller').'Controller'; $method = $request->getParameter('action').'Action'; $controller = new $class(); try { $response = $controller->$method($dispatcher, $request, $user); } catch (Exception $e) { $response = new sfWebResponse($dispatcher); $response->setStatusCode(500); $response->setContent(sprintf('An error occurred: %s', $e->getMessage())); } return $response; } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 29. I WANT a sfResponse Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 30. http://localhost/step_08.php/hello/Fabien try { if (!class_exists($class)) { throw new Exception('Controller class does not exist'); } $controller = new $class(); if (!method_exists($class, $method)) { throw new Exception('Controller method does not exist'); } $response = $controller->$method($dispatcher, $request, $user); if (!is_object($response) || !$response instanceof sfResponse) { throw new Exception('Controller must return a sfResponse object'); } } catch (Exception $e) { $response = new sfWebResponse($dispatcher); $response->setStatusCode(500); $response->setContent(sprintf('An error occurred: %s', $e->getMessage())); } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 31. The Application $response = $controller->$method($dispatcher, $request, $user); • I need a container for my application objects – The dispatcher – The user – The routing – The I18N – The Database – … • These objects are specific to my Application and does not depend on the request Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 32. http://localhost/step_09.php/hello/Fabien abstract class Application { public $dispatcher, $user, $routing; function __construct($dispatcher) { $this->dispatcher = $dispatcher; $this->configure(); } abstract function configure(); function handle($request) { return RequestHandler::handle($this, $request); } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 33. http://localhost/step_09.php/hello/Fabien class HelloApplication extends Application { function configure() { $storage = new sfSessionStorage(); $this->user = new sfUser($this->dispatcher, $storage); $this->routing = new sfPatternRouting($this->dispatcher); $this->routing->connect('hello', '/hello/:name', array('controller' => 'hello', 'action' => 'index')); } } $dispatcher = new sfEventDispatcher(); $request = new sfWebRequest($dispatcher); $application = new HelloApplication($dispatcher); $response = $application->handle($request); $response->send(); Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 34. Sensible defaults • Most of the time – The dispatcher is a sfEventDispatcher – The request is a sfWebRequest object – The controller must create a sfWebResponse object • Let’s introduce a new Controller abstract class • Modify the Application to takes defaults Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 35. http://localhost/step_10.php/hello/Fabien class Controller { public $application; function __construct($application) { $this->application = $application; } function renderToResponse($content) { $response = new sfWebResponse($this->application->dispatcher); $response->setContent($content); return $response; } } class helloController extends Controller { function indexAction($request) { $name = $request->getParameter('name', $this->application->user->getAttribute('name', 'World'))); $this->application->user->setAttribute('name', $name); return $this->renderToResponse('Hello '.$name); } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 36. http://localhost/step_10.php/hello/Fabien abstract class Application { function __construct($dispatcher = null) { $this->dispatcher = is_null($dispatcher) ? new sfEventDispatcher() : $dispatcher; $this->configure(); } function handle($request = null) { $request = is_null($request) ? new sfWebRequest($this->dispatcher) : $request; return RequestHandler::handle($this, $request); } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 37. Let’s have a look at the code Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 38. The directory structure • A directory for each application – An application class – A controller directory – A template directory Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 39. http://localhost/step_11.php/hello/Fabien class HelloApplication extends Application { function configure() { $storage = new sfSessionStorage(); $this->user = new sfUser($this->dispatcher, $storage); $this->routing = new sfPatternRouting($this->dispatcher); $this->routing->connect('hello', '/hello/:name', array('controller' => 'hello', 'action' => 'index')); $this->template = new Template(); $this->root = dirname(__FILE__); } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 40. http://localhost/step_11.php/hello/Fabien class Template { function render($template, $parameters = array()) { extract($parameters); ob_start(); require $template; return ob_get_clean(); } } class Controller { … function renderToResponse($templateName, $parameters = array()) { $content = $this->application->template->render($templateName, $parameters); $response = new sfWebResponse($this->application->dispatcher); $response->setContent($content); return $response; } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 41. Customization • Add some events in the RequestHandler – application.request – application.controller – application.response – application.exception • They can return a sfResponse and stop the RequestHandler flow Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 42. http://localhost/step_12.php/hello/Fabien $parameters = array('request' => $request); $event = new sfEvent($application, 'application.request', $parameters); $application->dispatcher->notifyUntil($event); if ($event->isProcessed()) { return $event->getReturnValue(); } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 43. What for? • Page caching – application.request: If I have the page in cache, unserialize the response from the cache and returns it – application.response : Serialize the response to the cache • Security – application.controller: Check security and change the controller if needed Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 44. class HelloApplication extends Application { function configure() { $storage = new sfSessionStorage(); $this->user = new sfUser($this->dispatcher, $storage); $this->routing = new sfPatternRouting($this->dispatcher); $this->routing->connect('hello', '/hello/:name', array('controller' => 'hello', 'action' => 'index')); $this->template = new Template(); $this->root = dirname(__FILE__); CacheListener::register($dispatcher, $this->root.'/cache/cache.db'); } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 45. class CacheListener { public $cache, $key; static function register($dispatcher, $database) { $listener = new __CLASS__(); $listener->cache = new sfSQLiteCache(array('database' => $database)); $dispatcher->connect('application.request', array($listener, 'listenToRequest')); $dispatcher->connect('application.response', array($listener, 'listenToResponse')); } function listenToRequest($event) { $this->key = md5($event->getParameter('request')->getPathInfo()); if ($cache = $this->cache->get($this->key)) { $this->setProcessed(true); $this->setReturnValue(unserialize($cache)); } } function listenToResponse($event, $response) { $this->cache->set($this->key, serialize($response); return $response; } } Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 46. Next symfony Workshops En français : Paris, France - Dec 05, 2007 In English : Paris, France - Feb 13, 2008 More info on www.sensiolabs.com Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 47. Join Us • Sensio Labs is recruiting in France – project managers – web developers • You have a passion for the web? – Web Developer : You have a minimum of 3 years experience in web development with Open-Source projects and you wish to participate to development of Web 2.0 sites using the best frameworks available. – Project Manager : You have more than 5 years experience as a developer and/or a project manager and you want to manage complex Web projects for prestigious clients. Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 48. SENSIO S.A. 26, rue Salomon de Rothschild 92 286 Suresnes Cedex FRANCE Tél. : +33 1 40 99 80 80 Fax : +33 1 40 99 83 34 Contact Fabien Potencier fabien.potencier@sensio.com http://www.sensiolabs.com/ http://www.symfony-project.com/ Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com