Your SlideShare is downloading. ×
0
symfony
                         symfony as a platform


                                  Fabien Potencier
              ...
symfony 1.1
  • A lot of internal refactoring… really a lot
  • Some new features… but not a lot
         – Tasks are now ...
Singletons
                         1.0                                            1.1
                    sfConfigCache  ...
Why?
  // somewhere in the backend application
  $frontendRouting = sfContext::getInstance('frontend')->getRouting();

  $...
symfony 1.0 Dependencies
                    sfView

                                               sfResponse
           ...
symfony 1.1 Dependencies
                                      sfRequest                    sfView
                       ...
sfEventDispatcher
  • Based on Cocoa Notification Center
  // sfUser
  $event = new sfEvent($this, 'user.change_culture', ...
Why?


     Let’s talk about symfony 2.0…




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

                The User asks a Resource in a Browser

          The Browser sends a Request to the Serv...
http://localhost/step_00.php?name=Fabien
  session_start();

  if (isset($_GET['name']))
  {
    $name = $_GET['name'];
  ...
sfWebRequest
                           PHP                                                              Object
  $_SERVER...
http://localhost/step_01.php?name=Fabien

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

  $dispatcher = new sfE...
sfWebResponse
                    PHP                                                            Object
  echo ‘Hello Worl...
http://localhost/step_02.php?name=Fabien
  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEv...
sfUser / sfStorage
                    PHP                                                           Object
  $_SESSION[‘n...
http://localhost/step_03.php?name=Fabien
  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfEv...
http://localhost/step_04.php?name=Fabien

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

  $dispatcher = new sfE...
sfRouting
  • Clean URLs <> Resources
  • Parses PATH_INFO to inject parameters in the
    sfRequest object
  • Several st...
http://localhost/step_05.php/hello/Fabien

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

  $dispatcher = new sf...
The Web Workflow

                The User asks a Resource in a Browser

          The Browser sends a Request to the Serv...
symfony 2.0 philosophy



               Request
                                               ?                         ...
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...
http://localhost/step_06.php/hello/Fabien
  require dirname(__FILE__).'/../symfony_platform.php';

  $dispatcher = new sfE...
http://localhost/step_06.php/hello/Fabien
  class helloController
  {
    function indexAction($dispatcher, $request, $use...
The RequestHandler
  • Handles the dispatching of the request
  • Calls the Controller
  • Has the responsability to retur...
http://localhost/step_07.php/hello/Fabien

  require dirname(__FILE__).'/../symfony_platform.php';
  require dirname(__FIL...
http://localhost/step_07.php/hello/Fabien
  class RequestHandler
  {
    function handle($dispatcher, $request, $user)
   ...
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('Contro...
The Application
  $response = $controller->$method($dispatcher, $request, $user);




  • I need a container for my applic...
http://localhost/step_09.php/hello/Fabien
  abstract class Application
  {
    public $dispatcher, $user, $routing;

     ...
http://localhost/step_09.php/hello/Fabien
  class HelloApplication extends Application
  {
    function configure()
    {
...
Sensible defaults
  • Most of the time
         – The dispatcher is a sfEventDispatcher
         – The request is a sfWebR...
http://localhost/step_10.php/hello/Fabien
  class Controller
  {
    public $application;

      function __construct($app...
http://localhost/step_10.php/hello/Fabien
  abstract class Application
  {
    function __construct($dispatcher = null)
  ...
Let’s have a look at the code




Symfony Camp 2007      www.symfony-project.com   fabien.potencier@sensio.com   www.sensi...
The directory structure
  • A directory for each application
         – An application class
         – A controller direc...
http://localhost/step_11.php/hello/Fabien
  class HelloApplication extends Application
  {
    function configure()
    {
...
http://localhost/step_11.php/hello/Fabien
  class Template
  {
    function render($template, $parameters = array())
    {...
Customization
  • Add some events in the RequestHandler
         – application.request
         – application.controller
 ...
http://localhost/step_12.php/hello/Fabien



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

  $event = new sfEvent($applic...
What for?
  • Page caching
         – application.request: If I have the page in cache,
           unserialize the respons...
class HelloApplication extends Application
  {
    function configure()
    {
      $storage = new sfSessionStorage();
   ...
class CacheListener
  {
    public $cache, $key;

      static function register($dispatcher, $database)
      {
         ...
Next symfony Workshops


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

     In English : Paris, France - Feb 13, 2008

  ...
Join Us
  • Sensio Labs is recruiting in France
         – project managers
         – web developers
  • You have a passi...
SENSIO S.A.
                                  26, rue Salomon de Rothschild
                                      92 286 S...
Upcoming SlideShare
Loading in...5
×

Symfony As A Platform (Symfony Camp 2007)

2,627

Published on

Published in: Technology, Sports, Career
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,627
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
43
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Symfony As A Platform (Symfony Camp 2007)"

  1. 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. 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. 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. 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. 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. 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. 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. 8. Why? Let’s talk about symfony 2.0… Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  9. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 22. Let’s create symfony 2.0… Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  23. 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. 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. 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. 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. 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. 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. 29. I WANT a sfResponse Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  30. 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. 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. 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. 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. 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. 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. 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. 37. Let’s have a look at the code Symfony Camp 2007 www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  38. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  1. A particular slide catching your eye?

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

×