Intro…
Now days the WebPages are outcome of heavy script processing in order to provide more dynamicity to page visitors. The utility of server side scripting is to adopt more engineering on web. When the page gets more visitors or becomes more popular, you have to ensure that, that traffic doesn’t stack or queued in front of your freaky web server. All you have to do is to serve them with your page and ofcourse serve it faster. Again server side scripting requires processing and compiling.
In order to serve pages faster, to make light use of server side processing and compiling and to survive within heavy traffic, caching dynamic script output is needed.
The Need For Speed…
Every time a request hits your web server, PHP has to do a lot of processing, all of your codes have to be compiled and executed for a single traffic hit every time. Interesting thing will be if the outcomes of all these processing is identical for each visitors. Say, processing happens every time for visitor 24500 and 24501 while the outputs are so same. Argh!!
What would be if we save the flat HTML generated for visitor 24500 and serve that to 24501 as well??? That will be awesome 😀 coz this leads to less processing and faster page handover. This da mechanism we are talking about, yeah! Cache PHP output 😀
Well we can write such optimization system but there is a smart package in PEAR called Cache_Lite that can do this job for us. Let’s check out why Cache_Lite:
- It saves time of writing new caching codes 😀
- It’s optimized for high traffic websites
- Robust, easy to implement
- Have time to time documentation
- Bunch of cool features. 🙂
Installation…
The Cache_Lite class comes courtesy of PEAR, the “PHP Extension and Application Repository” (http://pear.php.net). In case you didn’t know, PEAR is an online repository of free PHP software, including classes and modules for everything from data archiving to XML parsing. When you install PHP, a whole bunch of PEAR modules get installed as well; the Cache_Lite class is one of them.
In case not installed then…
It is just like coding hello world!! 😀
On ubuntu:
sudo aptitude -y update sudo aptitude install php-pear
Now that we have PEAR, i would use it to install the Cache_Lite extension
sudo pear install Cache_Lite
Perfect! 😀
Checking whether installed/ checking PEAR verson:
Both pear and pecl tools should be available everywhere on command line. For that to work, pear’s binary (bin) directory should be in your PATH variable.
To verify it works, simply type pear. A list of commands should be shown:
$ pear Commands: build Build an Extension From C Source bundle Unpacks a Pecl Package channel-add Add a Channel ...
You should further test that PEAR is up to date:
$ pear version PEAR Version: 1.7.2 PHP Version: 5.2.6RC4-pl0-gentoo Zend Engine Version: 2.2.0 Running on: Linux ...
More installation queries here: http://pear.php.net/manual/en/installation.checking.php
Implementation…
<?php // Include the package require_once('Cache/Lite.php'); // make sure cache_lite script path // Set a id for this cache $id = '123'; // Set a few options $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 3600 ); // Create a Cache_Lite object $Cache_Lite = new Cache_Lite($options); // Test if thereis a valide cache for this id if ($data = $Cache_Lite->get($id)) { // Cache hit ! // Content is in $data // (...) } else { // No valid cache found (you have to make the page) // Cache miss ! // Put in $data datas to put in cache // (...) $Cache_Lite->save($data); } ?>
More clearly…
<?php require_once "Cache/Lite.php"; $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 7200, 'pearErrorMode' => CACHE_LITE_ERROR_DIE ); $cache = new Cache_Lite($options); if ($data = $cache->get('id_of_the_page')) { // Cache hit ! // Content is in $data echo $data; } else { // No valid cache found (you have to make and save the page) $data = '<html><head><title>test</title></head><body><p>this is a test</p></body></html>'; echo $data; $cache->save($data); } ?>
If you wish use a cache per block and not a global cache, take as example the following script:
<?php require_once('Cache/Lite.php'); $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 3600 ); // Create a Cache_Lite object $Cache_Lite = new Cache_Lite($options); if ($data = $Cache_Lite->get('block1')) { echo($data); } else { $data = 'Data of the block 1'; $Cache_Lite->save($data); } echo('<br><br>Non cached line !<br><br>'); if ($data = $Cache_Lite->get('block2')) { echo($data); } else { $data = 'Data of the block 2'; $Cache_Lite->save($data); } ?>
Little bit implementation:
The key point is Cache_Lite maintains a unique identifier for every page. Cache_Lite will check for that identifier used before. If so, it will retrieve the stored HTML from disk (can use RAM as turbo charged storage i.e. mount tmpfs in RAM memory) and echo it right away. If not, we:
- turn on output buffereing so we can catch all following content
- we include the original PHP code
- catch the output buffer, and let Cache_Lite store it on disk for the next time.
- and then echo it
Example:
<?php /* Include the class */ require_once 'Cache/Lite.php'; /* Set a key for this cache item */ $id = 'newsitem1'; /* Set a few options */ $options = array( 'cacheDir' => '/var/www/www.mywebsite.com/cache/', 'lifeTime' => 3600 ); /* Create a Cache_Lite object */ $Cache_Lite = new Cache_Lite($options); /* Test if there is a valid cache-entry for this key */ if ($data = $Cache_Lite->get($id)) { /* Cache hit! We've got the cached content stored in $data! */ } else { /* Cache miss! Use ob_start to catch all the output that comes next*/ ob_start(); /* The original content, which is now saved in the output buffer */ include "requiredPhpFile.php"; /* We've got fresh content stored in $data! */ $data = ob_get_contents(); /* Let's store our fresh content, so next * time we won't have to generate it! */ $Cache_Lite->save($data, $id); ob_get_clean(); } echo $data; ?>
A Special case…
Say a case, is to automatically purge an article’s cache when a comment has been placed. You could for example place this before Cache_Lite checks if it’s got a cache page for a specific $id:
<?php if(isset($_POST["add_comment"]) && $_POST["add_comment"]){ $Cache_Lite->remove($id); } ?>
Docs for Cahe_Lite here:
http://pear.php.net/manual/en/package.caching.cache-lite.php
thanks…………….
LikeLike
Thanks Tonu for you hard work to write this helpful blog. This information will help me to build more effective web application..
Thanks! ones again. 🙂
LikeLike
Thanks tonu for your writing, it really help me.
LikeLike
Awesome post 😀
LikeLike
@Jewel, shuvo, mamun, ariful:
thnx bro. 😀
LikeLike
Great work 🙂
LikeLike
You are right – nowadays the web servers carry out too much complex processing to render a presentable web page. Here comes the necessity of a good caching mechanism.
Your article nicely explains the CACHE_LITE way of caching. Well done! Would be great if you extend this article to feature the caching of data driven blocks.
LikeLike
Many thnx Arif bhai. It’s an honor for me to get reply from “Big Guy” like you 😀
Also thnx for the valuable suggestions. 😀
LikeLike
Yeah….good job man. 😀 … hope u will keep posting such useful articles and keep us updated 😀 😀
LikeLike
Tonu vai, you wrote it very nicely. Very helpful tutorial to learn cache.
LikeLike
Ahsan bro: thnx for da reply 😀
LikeLike
Greatz,
Keep it up.
LikeLike
Nice work………………
LikeLike
Hi Tonu,
Nice write up. You write for a great point: Output caching/Page caching to improve performance. However, these days most of the websites are AJAXified, can you explain how this feature can benefit these AJAXified sites? Moreover, you can also consider caching resources like JavaScript files, CSS files, images and can employ CDN. I like the way you write……………………
LikeLike
Razan Da: thnx for your valuable reply 😀
These presented scheme of output caching can be used for Ajaxified sites too, we can use block caching method in this case also. More on, will be back
Your advice is always useful. 😀
LikeLike
thanks nice post, what is the difference between Cache_lite and eaccelerator?
u can find many helpful php info on newdailyblog.blogspot.com
LikeLike
thnx for the reading.
In sense of cache, eaccelerator cache PHP scripts in their compiled state where Cache_lite cache in their deploy state, this is the base diff. Again eaccelerator almost eliminates compiling overhead where Cache_lite eliminates processing and compiling overheads 😀 Isn’t it gr8.
Moreover eaccelerator found hilarious due to it’s optimizing capability.
LikeLike
Though I m not a good PHP programmer, But I learnt how easy to optimize the server’s load.
I realize, PHP is a smart web scripting language. Now, I have the conviction to work on PHP, work for PHP, work by PHP.
LikeLike
😀
LikeLike
Nice blog. Keep it up.
LikeLike
Nice writing…
Keep it up bro… (thumbs up)
LikeLike
Didn’t know PEAR itself has such an excellent Caching library. Awesome.
A little question.
In ur 1st, 2nd and 3rd example code block, you r saving the cache as :
$Cache_Lite->save($data);
Here you are not using id param (which u’ve used in 4th example). So, how will I retrieve this specific content? Is it somehow being set automatically from previous $Cache_Lite->get($id) ?
Thanks Tonu vai for ur great post. 🙂
LikeLike
Thnx for ur comments bro 😀
Lets check out the Cache_Lite::save function’s parameters:
boolean Cache_Lite::save ( string $data , string $id = NULL , string $group = ‘default’ )
I hope you got your answer 🙂 happy coding
LikeLike
Excellent writing. You can speed up the IO process more by storing the cache in ramdisk. it will be blazing fast 🙂
LikeLike
thnx Guru. for your reply. Yeah we can create turbo charged storage and allocate the cache storage to ram easily to provide more faster page serve. 😀
LikeLike
I still got confusion on how using Cache Lite per block. In this case, I want to cache QUERIES made by wordpress. I know I had to serialize the result first and then save it in the cache.
Where should I put the code? Should I replace every single call in the theme (like the_title, the_content, the_excerpt, etc) with some long lines of this following code?
$Cache_Lite = new Cache_Lite($options);
if ($data = $Cache_Lite->get(‘block1’)) {
echo($data);
} else {
$data = ‘Data of the block 1’;
$Cache_Lite->save($data);
}
Thanks..
LikeLike
in case of Caching block by block(group of html codes)
you can use simple cache per block scheme.
here is example:
$id_of_block1 = ‘block1’;
$id_of_block2 = ‘block2’;
//process block1
if ($data = $Cache_Lite->get($id_of_block1)) {
echo($data);
} else {
$data = ‘Data of the block 1’;
$Cache_Lite->save($data,$id_of_block1);
}
//process block2
if ($data = $Cache_Lite->get($id_of_block2)) {
echo($data);
} else {
$data = ‘Data of the block 2’;
$Cache_Lite->save($data,$id_of_block2);
}
LikeLike
all of your comments really help for me to understand on how to implement this. because i want to try the per block caching. thanks for a nice article.
LikeLike
You mdon’t need to use output buffering as there’s a subclass of the main Cache_Lite called Cache_Lite_Output() – this takes care of outputting the cached content and output buffer AND is a lot cleaner. All you need code wise is:
$cache = new Cache_Lite_Output($options);
if (!$cache->start($id)) {
//all php/html code to generate page
} else {
echo “\n\n\n” . ‘‘;
}
//thats it!
LikeLike
Well-known blog, by means of fellow that wrote so often. The power thing that writes to-date poop 🙂
LikeLike
I am using CouchCMS for making my blog but can’t figure out how to use Cache Lite for faster delivery. Though couch itself has the cache functionality but don’t know if it can change the speed of serving.
LikeLike