"Curiosity is the very basis of education and if you tell me that curiosity killed the cat, I say only the cat died nobly." - Arnold Edinborough

Edit: Part 2 is now available.

This is the first entry in a short series I’ll do on caching in PHP. During this series I’ll explore some of the options that exist when caching PHP code and provide a unique (I think) solution that I feel works well to gain high performance without sacrificing real-time data.

Caching in PHP is usually done on a per-object basis, people will cache a query or some CPU intensive calculations to prevent redoing these CPU intensive operations. This can get you a long way. I have an old site which uses this method and gets 105 requests per second on really old hardware.

An alternative that is used, for example in the Super Cache WordPress plug-in, is to cache the full-page data. This essentially mean that you create a page only once. This introduces the problem of stale data which people usually solve by checking whether data is still valid or by using a TTL caching mechanism and accepting stale data.

The method I propose is a spin on full-page caching. I’m a big fan of nginx and I tend to use it to solve a lot of my problems, this case is no exception. Nginx has a built-in Memcached module, with this we can store a page in Memcached and have nginx serve it – thus never touching PHP at all. This essentially turns this:

flattr this!

I love PHP, I really do… just, sometimes you fall into these situations where you just can’t help bang your head against the table until even the table starts bleeding.

I’m currently working on a blog series about intelligent caching with PHP. During the preparation for this I had to create a framework which could demonstrate the caching concepts I was going to be discussing, and what better than using namespaces for it. Namespaces makes auto loading easy as pie, they give you an incredible freedom in class naming due to the extra encapsulation layer and in general they’re just brilliant. Except for this.

$controller = '\Evil\Controller\News';
$data = $controller::dataKeyInvalidates($invalidate);

It simply wouldn’t work. I was certain it worked fine without namespaces so for kicks I tried this:

$data = \Evil\Controller\News::dataKeyInvalidates($invalidate);

And it ran without problems. Fun. What eventually let me figure out what was going on was by echoing the variable passed to my auto loader. When I used a variable to reference the class name the auto loader was passed “\Evil\Controller\News” when I didn’t the auto loader was passed “Evil\Controller\News”. Obviously some magic goes on inside PHP that translates \Evil\Controller\News into “Evil\Controller\News”. Setting $controller to ‘Evil\Controller\News’ made it work perfectly fine.

So to recap this:

// Does not work.
$controller = '\Evil\Controller\News';
$data = $controller::dataKeyInvalidates($invalidate); 

// Works.
$controller = 'Evil\Controller\News';
$data = $controller::dataKeyInvalidates($invalidate); 

// Works.
$data = \Evil\Controller\News::dataKeyInvalidates($invalidate); 

// Does not work.
$data = Evil\Controller\News::dataKeyInvalidates($invalidate);

flattr this!