130
HTTP caching and Symfony2 Be lazy, be ESI Alessandro Nadalin May, 13 2011

Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Embed Size (px)

DESCRIPTION

In the first part of the presentation we see how Symfony2 implements HTTP cache. In the second one there's an explanation of why application cache layers suck, why nerly every php application does caching in the less productive way and how you benefit from HTTP cache from this point of view.

Citation preview

Page 1: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

HTTP caching and Symfony2

Be lazy, be ESI

Alessandro NadalinMay, 13 2011

Page 2: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Symfony2 sucksat caching

Page 3: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

because it doesn't have an application caching layer

Page 4: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

high five, that's great

Page 5: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Sf2 embraces the HTTP caching specification

and that's not because

Page 6: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Fabien islazy

Page 7: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

that's because

Page 8: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Fabien kicks asses

Page 9: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

HTTP cache

is a

King

in Symfony2

Page 10: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Caching in Symfony2

Page 11: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Caching is, obviously, a matter of the response

Page 12: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

since the response is an object,we have some basic OO stuff

to handle HTTP cache

Page 13: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creating a response

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

return $res;}

Page 14: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creating a response

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

return $res;}

Page 15: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creating a response

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

return $res;}

Page 16: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creating a response

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

return $res;}

Page 17: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creating a response

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

return $res;}

Page 18: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creating a response

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

return $res;}

Page 19: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration

Page 20: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$date = new DateTime(); $date->modify('+600 seconds');

$res->setExpires($date);

return $res;}

Page 21: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$date = new DateTime(); $date->modify('+600 seconds');

$res->setExpires($date);

return $res;}

Page 22: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$date = new DateTime(); $date->modify('+600 seconds');

$res->setExpires($date);

return $res;}

Page 23: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration through Cache-Control

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$res->setMaxAge(600); $res->setSharedMaxAge(600);

return $res;}

Page 24: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration through Cache-Control

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$res->setMaxAge(600); $res->setSharedMaxAge(600);

return $res;}

Page 25: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration through Cache-Control

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$res->setMaxAge(600); $res->setSharedMaxAge(600);

return $res;}

Page 26: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Expiration through Cache-Control

public function indexAction(){ $res = $this->render('MyBundle:Default:home.html.twig', array( 'title' => 'My blog', ));

$res->setMaxAge(600); $res->setSharedMaxAge(600);

return $res;}

Shared caches, like Symfony2 reverse proxy

Page 27: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation

Page 28: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation

public function articleAction($id){ $article = $this->get('entity_manager')->query($id)... $res = $this->render('MyBundle:Default:article.html.twig', array( 'article' => '$article', ));

$etag = "article:{$article->getId()}:{$article->getVersion()}";

$res->setETag($etag); $res->setLastModified($article->getModifiedAt());

return $res;

Page 29: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation

public function articleAction($id){ $article = $this->get('entity_manager')->query($id)... $res = $this->render('MyBundle:Default:article.html.twig', array( 'article' => '$article', ));

$etag = "article:{$article->getId()}:{$article->getVersion()}";

$res->setETag($etag); $res->setLastModified($article->getModifiedAt());

return $res;

Page 30: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation

public function articleAction($id){ $article = $this->get('entity_manager')->query($id)... $res = $this->render('MyBundle:Default:article.html.twig', array( 'article' => '$article', ));

$etag = "article:{$article->getId()}:{$article->getVersion()}";

$res->setETag($etag); $res->setLastModified($article->getModifiedAt());

return $res;

Page 31: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation

public function articleAction($id){ $article = $this->get('entity_manager')->query($id)... $res = $this->render('MyBundle:Default:article.html.twig', array( 'article' => '$article', ));

$etag = "article:{$article->getId()}:{$article->getVersion()}";

$res->setETag($etag); $res->setLastModified($article->getModifiedAt());

return $res;

Page 32: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation

public function articleAction($id){ $article = $this->get('entity_manager')->query($id)... $res = $this->render('MyBundle:Default:article.html.twig', array( 'article' => '$article', ));

$etag = "article:{$article->getId()}:{$article->getVersion()}";

$res->setETag($etag); $res->setLastModified($article->getModifiedAt());

return $res;

Datetime object

Page 33: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Automagically get a Datetime from Doctrine2

namespace Acme\BlogBundle\Entity;

/** * @orm:Entity * @orm:Table(name="article") */class Article{ /** * @orm:Column(type="datetime", name="modified_at") */ protected $modifiedAt;

Page 34: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Automagically get a Datetime from Doctrine2

namespace Acme\BlogBundle\Entity;

/** * @orm:Entity * @orm:Table(name="article") */class Article{ /** * @orm:Column(type="datetime", name="modified_at") */ protected $modifiedAt;

Page 35: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

but hey, you say

Page 36: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

what's the advatage of using validation if we always hit

the DB and create a new Response?

Page 37: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation, the right way

public function articleAction($id){ $res = new Response()

$etag = Memcache::get("Article:{$id}:etag"); $lastModified = Memcache::get("Article:{$id}:last_modified");

$res->setETag($etag); $res->setLastModified($lastModified);

if ($res->isNotModified($this->get('request'))) { return $res; }

$article = $this->get('entity_manager')->query($id)... ...

Page 38: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation, the right way

public function articleAction($id){ $res = new Response()

$etag = Memcache::get("Article:{$id}:etag"); $lastModified = Memcache::get("Article:{$id}:last_modified");

$res->setETag($etag); $res->setLastModified($lastModified);

if ($res->isNotModified($this->get('request'))) { return $res; }

$article = $this->get('entity_manager')->query($id)... ...

Page 39: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation, the right way

public function articleAction($id){ $res = new Response()

$etag = Memcache::get("Article:{$id}:etag"); $lastModified = Memcache::get("Article:{$id}:last_modified");

$res->setETag($etag); $res->setLastModified($lastModified);

if ($res->isNotModified($this->get('request'))) { return $res; }

$article = $this->get('entity_manager')->query($id)... ...

Page 40: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Validation, the right way

public function articleAction($id){ $res = new Response()

$etag = Memcache::get("Article:{$id}:etag"); $lastModified = Memcache::get("Article:{$id}:last_modified");

$res->setETag($etag); $res->setLastModified($lastModified);

if ($res->isNotModified($this->get('request'))) { return $res; }

$article = $this->get('entity_manager')->query($id)... ...

Page 41: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

relax

Page 42: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Calculating an Etag, or a date, is cheaperthan generating a full MVC response

Page 43: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Control your power

Page 44: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Additional management

public function articleAction($id){ $res = new Response()

$res->setVary(array( 'Accept-Encoding', ));

$res->setPublic();

$res->setNotModified();

...

Page 45: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Varying the response

public function articleAction($id){ $res = new Response()

$res->setVary(array( 'Accept-Encoding', ));

$res->setPublic();

$res->setNotModified();

...

Page 46: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Cacheable by all caches

public function articleAction($id){ $res = new Response()

$res->setVary(array( 'Accept-Encoding', ));

$res->setPublic();

$res->setNotModified();

...

Page 47: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

or by local only

public function articleAction($id){ $res = new Response()

$res->setVary(array( 'Accept-Encoding', ));

$res->setPrivate();

$res->setNotModified();

...

Page 48: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Good old 304

public function articleAction($id){ $res = new Response()

$res->setVary(array( 'Accept-Encoding', ));

$res->setPrivate();

$res->setNotModified();

...

Page 49: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Stale

public function articleAction($id){ $res = new Response()

$res->setVary(array( 'Accept-Encoding', ));

$res->setPrivate();

$res->expire();

...

Page 50: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

but hey, you say

Page 51: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

HTTP's cache fails when dealing with really dynamic pages, because consumers will always have to hit the origin server, although a part of the page would be cacheable ( header and

footer, for example )

Page 52: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

no bueno, you say

Page 53: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

NOPE

Page 54: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

ESI was built for thathttp://www.w3.org/TR/esi-lang

<esi:include src="http://mysite.com/twitterfeeds.html" />

Page 55: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

ESI and Symfony2

# controller$response->setSharedMaxAge(3600);

# app/config/config.ymlframework: esi: { enabled: true }

# template{% render '...:twitterFeeds' with {}, {'standalone': true} %}

# fragment controller$response->setSharedMaxAge(15);

Page 56: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

ESI and Symfony2

# controller$response->setSharedMaxAge(3600);

# app/config/config.ymlframework: esi: { enabled: true }

# template{% render '...:twitterFeeds' with {}, {'standalone': true} %}

# fragment controller$response->setSharedMaxAge(15);

Page 57: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

ESI and Symfony2

# controller$response->setSharedMaxAge(3600);

# app/config/config.ymlframework: esi: { enabled: true }

# template{% render '...:twitterFeeds' with {}, {'standalone': true} %}

# fragment controller$response->setSharedMaxAge(15);

Page 58: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

ESI and Symfony2

# controller$response->setSharedMaxAge(3600);

# app/config/config.ymlframework: esi: { enabled: true }

# template{% render '...:twitterFeeds' with {}, {'standalone': true} %}

# fragment controller$response->setSharedMaxAge(15);

Page 59: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

ESI and Symfony2

# controller$response->setSharedMaxAge(3600);

# app/config/config.ymlframework: esi: { enabled: true }

# template{% render '...:twitterFeeds' with {}, {'standalone': true} %}

# fragment controller$response->setSharedMaxAge(15);

Page 60: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Use Symfony2 reverse proxy

Page 61: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Use Symfony2 reverse proxy(slower)

Page 62: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

or Varnish

http://www.varnish-cache.org/

Page 63: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Varnish configuration

backend apache { .host = "127.0.0.1"; .port = "8080";}

sub vcl_recv { unset req.http.Accept-Encoding; unset req.http.Vary; set req.http.Surrogate-Capability = "abc=ESI/1.0";}

sub vcl_fetch { esi;

...

Page 64: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Varnish configuration

backend apache { .host = "127.0.0.1"; .port = "8080";}

sub vcl_recv { unset req.http.Accept-Encoding; unset req.http.Vary; set req.http.Surrogate-Capability = "abc=ESI/1.0";}

sub vcl_fetch { esi;

...}

tell Symfony2 you're behind a reverse proxyable to handle the ESI specification

Page 65: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Why HTTP cachingis so

important?

Page 66: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Ask yourself:as a developer, what do I want

on my application?

Page 67: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Evolve

Loose coupling

Work less

Page 68: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Evolve Because you want your platform to extensible

Loose coupling

Work less

Page 69: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Evolve Because you want your platform to extensible

Loose coupling Because you want it to be easy to integrate with, evolve, plug and mantain

Work less

Page 70: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Evolve Because you want your platform to extensible

Loose coupling Because you want it to be easy to integrate with, evolve, plug and mantain

Work less

Because every LoC is bug-prone and our man-day is a hard-to-scale cost

Page 71: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

enters our Hero #1

Page 72: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Page 73: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Page 74: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

enters our Hero #2

Page 75: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Page 76: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

http://www.lullabot.com/articles/a-beginners-guide-to-caching-data

Page 77: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

2007

Page 78: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

2011?

Page 79: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

it supportsHTTP caching!

http://drupal.org/node/147310

Page 80: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

it supportsHTTP caching!

http://drupal.org/node/147310

( people is supposed to clap their hands here )

Page 81: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

but

Page 82: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

wait.... how?

Page 83: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Default headers

Expires = 'Sun, 19 Nov 1978 05:00:00 GMT',

Cache-Control = 'no-cache, must-revalidate',

ETag = $_SERVER['REQUEST_TIME'],

Page 84: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Default headers

Expires = 'Sun, 19 Nov 1978 05:00:00 GMT',

Cache-Control = 'no-cache, must-revalidate',

ETag = $_SERVER['REQUEST_TIME'],

Page 85: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Default headers

Expires = 'Sun, 19 Nov 1978 05:00:00 GMT',

Cache-Control = 'no-cache, must-revalidate',

ETag = $_SERVER['REQUEST_TIME'],

Page 86: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Default headers

Expires = 'Sun, 19 Nov 1978 05:00:00 GMT',

Cache-Control = 'no-cache, must-revalidate',

ETag = $_SERVER['REQUEST_TIME'],

Page 87: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

is that even legal?

Page 88: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

"but you can redefine them!"

Page 89: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header()

Page 90: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

function drupal_add_http_header(){ ...

...

drupal_send_headers($headers);}

Page 91: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

so, what

drupal_send_headers()

can do so evil?

Page 92: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

header(),

of course

Page 93: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

which means

Page 94: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header('Dumb-Header', 'I\'m batman!');...// other logic...drupal_add_http_header('Dumb-Header', 'I\'m not');

var_dump(headers_list());

Page 95: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header('Dumb-Header', 'I\'m batman!');...// other logic...drupal_add_http_header('Dumb-Header', 'I\'m not');

var_dump(headers_list());

array 0 => string 'X-Powered-By: PHP/5.3.2-1ubuntu4.7' 1 => string 'Cache: I'm not'

Page 96: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header('Dumb-Header', 'I\-m batman!');...// other logic...drupal_add_http_header('Dumb-Header', false);

var_dump(headers_list());

Page 97: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header('Dumb-Header', 'I\-m batman!');...// other logic...drupal_add_http_header('Dumb-Header', false);

var_dump(headers_list());

array 0 => string 'X-Powered-By: PHP/5.3.2-1ubuntu4.7' 1 => string 'Cache: I'm batman'

Page 98: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header('Dumb-Header', 'I\-m batman!');...// other logic...drupal_add_http_header('Dumb-Header', ' ');

var_dump(headers_list());

Page 99: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

drupal_add_http_header('Dumb-Header', 'I\-m batman!');...// other logic...drupal_add_http_header('Dumb-Header', ' ');

var_dump(headers_list());

array 0 => string 'X-Powered-By: PHP/5.3.2-1ubuntu4.7' 1 => string 'Cache:'

Page 100: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

or

Page 101: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

you can use header_remove()

( PHP 5.3 )

Page 102: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

and create a new class to manage/keep track of

headers and caching directives

Page 103: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

but we're lazy

and

we don't want to reinvent the wheel

Page 104: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Goals

Work lessevolve

loose coupling

Page 105: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Goals

Work lessevolve

loose coupling

Page 106: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

everything is done for us!

:)

but....

Page 107: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

tmp files, cache tables, procedural code...

mmmmh....

gotta be something better

Page 108: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Frameworks

Page 109: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Page 110: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

symfony ONE

Page 111: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Cache is used for compiling routes, autoloading, ...

Page 112: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Cache is used for compiling routes, autoloading, ...

...but also for storing the view

Page 113: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Goals

Work lessevolve

loose coupling

Page 114: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Goals

Work lessevolve

loose coupling

Page 115: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

at least because we use a framework

Page 116: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

HTTP

Page 117: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Goals

Work lessevolve

loose coupling

Page 118: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Less work

Page 119: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

because the hard work is delegated to the browser/proxy

Page 120: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Evolve

Page 121: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

because cache is abstracted from the application

Page 122: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Loose coupling

Page 123: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

because caching is bound to the protocol, HTTP, not to your implementation ( Sf, RoR, Django )

Page 124: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Alessandro Nadalin

Page 125: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Alessandro Nadalin

Page 126: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Alessandro Nadalin

odino.org

Page 127: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Alessandro Nadalin

odino.org@_odino_

Page 128: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Alessandro Nadalin

odino.org@_odino_http://joind.in/talk/view/2988

Page 129: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Alessandro Nadalin

odino.org@_odino_http://joind.in/talk/view/2988

Thanks!

Page 130: Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

Creditshttp://www.flickr.com/photos/snakphotography/5004775320/sizes/o/in/photostream/

http://www.flickr.com/photos/ashatenbroeke/4367373081/sizes/z/in/photostream/http://www.flickr.com/photos/juanpg/3333385784/sizes/z/in/photostream/http://www.flickr.com/photos/congvo/301678287/sizes/l/in/photostream/

http://www.flickr.com/photos/adamrice/280300202/sizes/l/in/photostream/http://www.flickr.com/photos/tomer_a/541411897/sizes/o/in/photostream/http://www.flickr.com/photos/subpra/4514008262/sizes/l/in/photostream/

http://www.flickr.com/photos/lippincott/2539720043/sizes/l/in/photostream/http://www.flickr.com/photos/rawryder/5086090931/sizes/l/in/photostream/http://www.flickr.com/photos/robboudon/5312731161/sizes/l/in/photostream/

http://www.flickr.com/photos/bc-burnslibrary/4158243488/sizes/o/in/photostream/http://www.flickr.com/photos/13606325@N08/2416993706/sizes/o/in/photostream/

http://www.flickr.com/photos/neothezion/5135841069/sizes/l/in/photostream/http://www.flickr.com/photos/planetschwa/2494067809/http://www.flickr.com/photos/thomasthomas/258931782/

http://www.flickr.com/photos/jungle_boy/220181177/sizes/l/in/photostream/http://www.flickr.com/photos/ramduk/3708039504/sizes/z/in/photostream/

http://www.flickr.com/photos/sashawolff/3228711025/sizes/l/in/photostream/