If your website receives a good amount of traffic every day and your web pages are loading slow, you might want to consider implementing some sort of caching mechanism on your website to speed up page loading time. Because as we all know that each client-server request consists of many queries, loops, calculations, database queries etc. these all add up to processing time, which eventually increases page loading time. The simplest way to avoid all these is to create cache files and store them in a separate directory, which can later be served as fast loading static pages instead of dynamically generated pages.
There are several other PHP cache engines such as APC, Xcache or OPcache to boost your application performance, but they all work quite differently if you are curious; you can always find plenty of articles and tutorials written about them on the web. But here you’ll learn the simplest way of caching PHP pages, and that is using PHP’s core output Buffer and Filesystem, combining these two functions we can have a magnificent caching system..
PHP Output buffer :— It interestingly improves performance and decreases the amount of time it takes to download, because the output is not being sent to browser in pieces but the whole HTML page as one variable. The method is insanely simple take a look at the code below :
1 2 3 4 5 6 7 | <?php ob_start(); // start the output buffer /* the content */ ob_get_contents(); gets the contents of the output buffer ob_end_flush(); // Send the output and turn off output buffering ?> |
First line ob_start() turns the output buffering on, which means anything after this will be stored in the buffer and to retrive the contents of the output buffer we simply call ob_get_contents(). The ob_end_flush() at the end of the code turns buffering off.
PHP Filesystem :— is a also a part of the PHP core, which allow us to read and write the file system.
1 2 3 | $fp = fopen('/path/to/file.txt', 'w'); //open file for writing fwrite($fp, 'I want to write this'); //write fclose($fp); //Close file pointer |
As you can see the first line of the code fopen() opens the file for writing, the mode ‘w’ places the file pointer at the beginning of the file and if file does not exist, it attempts to create one. Second line fwrite() writes the string to the opened file, and finally fclose() closes the successfully opened file at the beginning of the code.
Now you should be pretty clear about PHP output buffer and filesystem, we will use both methods to create our simple PHP caching system. Please have a look at the picture below, the flowchart gives you the basic idea of our cache system.
The cycle starts when a user requests the content, the script simply checks and outputs the cache copy of requested page, if it doesn’t a new copy is created and sent to the browser.
Below is the full example of PHP caching system, you can examine, copy it into your PHP project and play with code, it should work as expected. You can modify the cache expire time, cache file extension, ignored pages etc. to suit your needs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <?php //settings $cache_ext = '.html'; //file extension $cache_time = 3600; //Cache file expires afere these seconds (1 hour = 3600 sec) $cache_folder = 'cache/'; //folder to store Cache files $ignore_pages = array('', ''); $dynamic_url = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url) $cache_file = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file $ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired. ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip. readfile($cache_file); //read Cache file echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->'; ob_end_flush(); //Flush and turn off output buffering exit(); //no need to proceed further, exit the flow. } //Turn on output buffering with gzip compression. ob_start('ob_gzhandler'); ######## Your Website Content Starts Below ######### ?> <!DOCTYPE html> <html> <head> <title>Page to Cache</title> </head> <body> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ut tellus libero. </body> </html> <?php ######## Your Website Content Ends here ######### if (!is_dir($cache_folder)) { //create a new folder if we need to mkdir($cache_folder); } if(!$ignore){ $fp = fopen($cache_file, 'w'); //open file for writing fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file fclose($fp); //Close file pointer } ob_end_flush(); //Flush and turn off output buffering ?> |
Here’s quick points to help you understand the code:
I hope this script helps you create your own simple caching system, but you must avoid caching certain types of pages such as members area (after users log in), search pages or constantly updating pages, your users will experience undesirable outcomes. And remember just caching pages isn’t enough, consider combining and compressing JavaScripts, CSS to boost performance, even more, use various tricks and tips, dig deeper, use free tools like Google’s pageSpeed, Chrome DevTools to analyze performance of your website, good luck.
Thanks, Saran, i implemented it and works perfect :)
ReplyWell Done and thanks dude.Its very helpful ,i will use these thoughts in my projects development. Good Luck :)
ReplyIt works great!!
ReplyThanks a lot Saran for this good article, such a nice explanation you gave. I’m sure this will help me a lot in reducing my site load time because website load time is what do or break your online presence especially when you are in a competitive market such as news, entertainment or sports for an instance.
ReplyI have tried to integrate your code in my site.it have some issue in that.my site have header.php,footer.php file in seperate ,so add code in both file as like your demo code.when i run site,it output the cache for footer section only.it not including header and content part in cache output.Is there any solution for this issue?
ReplyThis code is working in chrome but not in mozilla
ReplyThank you so much for this script, working fine… but sometimes cache file does not delete automatically. Can you please advice me.
ReplyExcellent code save lot’s of time. Great keep posting.
ReplyHi, this is great but how can i set the $cache_time for like 7 days instead of seconds?
Reply7 days = 604800 Seconds
https://www.timecalculator.net/hours-to-seconds
It seem to work only if you set the $cache_time below 24 hours (86400 sec.) or else it will create a new cache file because the code checks only at what time the existing cache file was created not the date…
This cache script works perfect wrapping the index.php of a prestashop installation:
Combining some rules in https://github.com/CleverCloud/varnish-examples/blob/master/prestashop.vcl works perfect .
You only have to add the URL for shopping cart and avoid any cache when a POST request is made with:
if ($_SERVER[‘REQUEST_METHOD’] != ‘GET’) {
$ignore = true;
}
Ask us any information if you want to implement it in a prestashop system: https://www.imaginacolombia.com
Regards
ReplyVery helpful information and add insight .. Thanks
ReplyThank you, thank you, thank you.
ReplyHi Steve,
I want to use cache system in my list pages. But I have some dynmic fields like a vote buttons or ‘an hour ago’ etc.
What should I do? I need logical behind more than codes. Thank u.
ReplyHey! thanks for the code. It works great!
ReplyThanks a lot for this great cache script!
ReplyI visit your site often while there is a lot of interesting info for me.
After putting this script into a page and testing it, the loading time decreased from about 400ms to 60ms!!!!!
Hey, this worked great, thank you so much for the code!!!
ReplyAlso, how do you flush the cache when you’ve updated the page (let’s say you’re doing testing) and want to see the updated page? Is there an easy part in the code to comment out? Thanks!
thanks for this tutorial, very helpfull
ReplyHow about image ? Is including too on cache file? My html content using a lot of images that make loading take long time.
ReplyUse CDN for images.
hmmm :D thanks, its really help
Replyif i a have a dynamic page which fetches 5 records from database.
Replytomorrow someone adds the sixth record
and i again hit the same url will it show me 5 records or 6 records ?
what do you mean by this : if the Web developer manually edits the file
All that is required of you is to set an appropriate cache time. In my case, I will be modifying the code, I can use an unlimited cache time, since all my content is moderated, and I shall be coding a cache purge upon authorizing a change to the site. You may consider this technique for yourself, if it is a special interest to your situation, on top of a cache time, as well.