Last year, I have created a post about page caching in PHP. It was written in Kohana and was incorporated to my collection of classes that was packed into a single module. This time, I created Pagecache module for Kohana to separate it from all my other classes.
DC Pagecache
A simple page caching for kohana. Get the source code in github:
https://github.com/lysender/pagecache
When to use?
- When you are serving mostly static content.
- When content does not change for a long period of time.
- When you simply want page caching and knows when to clear cache.
How to use?
Simple. For a given URI (request), you will capture the output and feed it to the pagecache object. The pagecache object will then save the output to a directory. The next time the user requests the same URI, your webserver will serve the cached content without bothering Kohana.
You will just need to configure the following:
- Publicly accessible directory where you save the cached content.
- A certain URI pattern that can actually match a valid filename (ex: no space).
- A
RewriteRulethat will serve the cached content for a given URI. - A
controllerthat will capture the output of the request and will save it to cache.
Configuration
The default cache directory is at DOCROOT/media/pagecache but you can change it anytime. This is the default config at MODPATH/pagecache/config/pagecache.php:
return array( 'cache_dir' => DOCROOT.'media/pagecache' );
Assuming that DOCROOT/media is accessible directly from the outside world.
URI pattern
It is assumed that your URI can be directly mapped to a valid filename. The table below shows the URI to filename mapping:
| URI | Filename |
|---|---|
/ |
/index.html |
/contact |
/contact/index.html |
/about/mission |
/about/mission/index.html |
Using the default config, it will map to:
| URI | Filename |
|---|---|
/ |
/media/pagecache/index.html |
/contact |
/media/pagecache/contact/index.html |
/about/mission |
/media/pagecache/about/mission/index.html |
Simple isn’t it?
The Rewrite Rule
In your .htaccess file, you will have something like this:
# BEGIN Page cache RewriteRule ^/(.*)/$ /$1 [QSA] RewriteRule ^$ media/pagecache/index.html [QSA] RewriteRule ^([^.]+)/$ media/pagecache/$1/index.html [QSA] RewriteRule ^([^.]+)$ media/pagecache/$1/index.html [QSA] # END Page cache
The Rewrite rule above will accomplish the URI pattern matching.
Capturing and saving output / page
The basic usage goes like this:
Pagecache::factory('/the/requested/uri')
->write($the_page_output);
Currently, I used a controller to facilitate the page caching. Once a controller extends to this controller, it will automatically trigger output to be cached.
abstract class Controller_Cached extends Controller_Template
{
public function after()
{
parent::after();
$uri = Arr::get($_SERVER, 'REQUEST_URI', $this->request->uri());
Pagecache::factory($uri)
->write($this->response->body());
}
}
It assumes that the controller uses a template. Once the after() method is called, it will capture the response and save it to cache using the current request URI.
For example you have a controller Controller_Faq, you can serve cached page by extending the Controller_Cached.
class Controller_Faq extends Controller_Cached {
// The rest of the code here
Cleaning up
To cleanup your cached pages, simple call: Pagecache::cleanup(). Call it via a cron job with a certain interval.
Tests?
Currently, I haven’t created unit tests for the Pagecache module. Anyway, for comments, suggestions and issues, comment on github or drop me a message at: theman [at] lysender [dot] com.