HTTP cache management with Symfony2

0 gravatar By Grégoire Marchal - 08/27/2012

Before reading this post, you should read the Symfony documentation about cache. As usual it's clear, and it allows me to not have to explain everything :).

For this blog, the strategy I've chosen is this: to display a post, I use the its last modification date to define the "Last-Modified" HTTP header. If I see through the request that the client has already this version in the cache, then I can stop the process and return the 304 "Not Modified" HTTP code. Otherwise, I continue the process to serve the page to the client, so he can store it in his cache.

So my controller looks like this:

public function displayAction(Post $post)
{
    $response = new Response();
    $response->setLastModified($post->getModificationDate());
    $response->setPublic();

    if ($response->isNotModified($this->getRequest())) {
        return $response; // this will return the 304 if the cache is OK
    }

    // Do some stuff here...

    return $this->render('...:display.html.twig', array(
        'post' => $post,
        // ...
    ), $response);
}

The first 3 lines allow to define the strategy used for cache management. Note the setPublic() call to define that the cache is the same for all the users, and not private to the current user. It allows the shared caches (proxy caches and gateway caches) to also store the cache. Thereby, if user A has already displayed a post, user B can use the cache generated by user A, without generating the whole page. In my case, Symfony2 is the gateway cache.

Then I call the $response->isNotModified() method, giving the request as parameter. So it's the framework that decides if a 304 code must be returned or not, by comparing the "Last-Modified" header date (we've just defined it) with the "If-Modified-Since" header date provided by the client (the date of the post version he has in the cache). If the post hasn't been modified since it has been cached, we just have to return the response object, that represent the 304 "Not Modified" code.

Otherwise, we continue the controller process. In my case, I just need to prepare the comment form. Then I render the template. Don't forget to give the $response object as 3rd parameter of the $this->render() method, so the "Last-Modified" header will be added to the response; if you forget it, Symfony will create a default Response object, without any cache control header, so the clients will never store the page in the cache!

I'll soon talk about the edge side includes to handle the blog left column caching strategy, and about the event listeners to handle the post modification date, taking the comments into account...

See you later!

Symfonic.fr is now powered by Symfony2

0 gravatar By Grégoire Marchal - 08/25/2012

Here is the new blog! Many changes: new hosting, new look'n'feel, new engine, and new topic: Symfony2 time! It was high time to rejuvenate symfonic.fr, now it's done.

About the hosting, I was on a low cost OVH shared hosting: easy to use, but too restrictive when you want to have some fun... So I've switched to a Virtual Private Server (Kimsufi / OVH), small version, (well advised by @bourvill, OVH expert ;)). With few RAM (512MB), I've chosen nginx (+ php-fpm) instead of apache, and I really don't regret! It's light and fast, as you can see! For the rest of the "sys admin" part, I'm not an expert, so I've followed this tutorial (FR).

About the look'n'feel, it's simple. You might have recognized the twitter bootstrap. Simple, clean, nice: I like. And W3C valid!

About the backend, I've said goodbye to wordpress, and hello to Symfony2 of course! As a basis, I've used the tutorial from le site du zero (FR), then I've added the functionalities I need: multilingual management, cache management, admin part, RSS feed, ... I'll explain some of these points in the next posts.

And if you notice any bug, think about enhancements or anything else, please tell me on github!

Some news...

0 gravatar By Grégoire Marchal - 08/14/2012

It's been a while since I've written on this blog. I had good reasons for that, here is a non-exhaustive list of my excuses, randomly ordered:

  • I had a lot of work
  • I wasn't motivated to write about symfony 1, since it's near the end of its life
  • I had no inspiration
  • My tasks were not interesting enough to be blogged
  • The sun shines (no, it doesn't...)
  • The olympic games were on! (ok, I know, it didn't start 1.5 year ago...)

Anyway, I always had a good reason! But i'ts over now, it will change, I hope so! First of all because I finally take up Symfony2: I'm currently working on the rewriting of this blog engine, to get free from wordpress! I discover a lot of new things, I have some issues, I search and find solutions, and I even do some pull requests! So I hope I'll have some exciting stuff to tell you, and I'll be motivated to share it!

Stay tuned!