I am a metal monkey!
Administrator Community Supporter?
Jedai Sword Master
Gender:
Posts: 5779
46271 credits Members referred : 3
« on: Nov 24, 2005, 03:21:27 pm »
Introduction
In this article I will try to give a view of what is the custom caching with php, why and how we can use it.
In the modern days, most of the sites are database driven. That means that your site is actually an application which retrieves data from a DBMS ( database managment system, eg MySQL) , parses the data and shows the result to the user. Most of these data are usually don't change frequently or don't change at all, and the reason that we use the database is that we can easilly update the site and the content.
A problem that this process creates is the server overhead. Every time we execute a query in the database, the instance of our script will call the DBMS, and then the DBMS will send the results of the query. This is time consuming, and especcially for sites with heavy traffic is a real big problem.
How we can solve this problem?
There are two ways to solve this if you want to make your site faster. First is optimizing the queries, but we will not talk about this at the present article. The second and most valuable is using some kind of custom caching technique.
Custom caching with php
First let me explain the idea behind custom caching. When we have dynamic pages that their data is not updated frequently, we can use a 'system' that will be able to create the page, and then store it for later use. That means that after the page's creation, our application will not run the queries again in order to display the page, but it will show the cached one. Of course this system must be able to keep the cached pages for a time period that we will set.
Let's code it
Here is a simple class that will do the job. Let's see the code first :
Code:
<?php class cache { var $cache_dir = './tmp/cache/';//This is the directory where the cache files will be stored; var $cache_time = 1000;//How much time will keep the cache files in seconds.
var $caching = false; var $file = '';
function cache() { //Constructor of the class $this->file = $this->cache_dir . urlencode( $_SERVER['REQUEST_URI'] ); if ( file_exists ( $this->file ) && ( fileatime ( $this->file ) + $this->cache_time ) > time() ) { //Grab the cache: $handle = fopen( $this->file , "r"); do { $data = fread($handle, 8192); if (strlen($data) == 0) { break; } echo $data; } while (true); fclose($handle); exit(); } else { //create cache : $this->caching = true; ob_start(); } }
function close() { //You should have this at the end of each page if ( $this->caching ) { //You were caching the contents so display them, and write the cache file $data = ob_get_clean(); echo $data; $fp = fopen( $this->file , 'w' ); fwrite ( $fp , $data ); fclose ( $fp ); } } }
//Example : $ch = new cache(); echo date("D M j G:i:s T Y"); $ch->close(); ?>
Now let me explain :
function cache()
This is the constructor function of the class. The job of this function is to check if there is a cached file for the page that we want, or it should create it. Here is how this is done :
Here we check if there is a cached version of this page, and if the file must be recreated because it has expired. If the file is cached, it will show the cached page and the exit. I will explain later why exit. If the cached file must be created this code will be executed :
$this->caching = true; ob_start();
The first statement indicates to the close() function that it is creating the cache file, and the ob_start() will start buffering the output. The buffer's data will be used later by the close() function to save the cache file.
function close()
This function must be called from the end of your script, and it will do the rest of the job. Actually it is needed only when we are in the process of caching that's why it starts with the statement if ( $this->caching ) Let me explain what is happening here :
$data = ob_get_clean();
Here we get all the data from the output buffer while we unset it, and put the data in the $data variable. The four statements that folow up are showing the data and then write the cache file.
Troubleshooting
This is a very simple class, and the purpose is to learn how you can implement a caching solution for your site. The obligation using this class is that you must use it only in this form :
Code:
<?php $a = new cache(); .... .... .... $a->close(); ?>
If you have code after the $a->close() statement, the class will not work right. This is because of the exit() statement in the cache() function.
Of course you can take this code and make it work for your own needs.
A quick solution is to remove the exit() statement in the cache() function and then use the class this way :
Code:
<?php $a = new cache(); if ( $a->caching ) { .... .... .... } $a->close(); ?>
Hope this helped.
You can publish this article to your site, but only if you give back credit, and a link to http://www.webdigity.com/
Global Moderator
Internet Junkie
Gender:
Posts: 1525
6359 credits Members referred : 8
Gimme all your cookies!!!
« Reply #1 on: Nov 24, 2005, 04:30:50 pm »
I can see this being very useful on very busy pages that don't change often at all. I will remember that your script is here for later when I need it...
I have this sql query that takes around 30 sec to complete. The query searches through 40000 clients and is very complicated; I wish that I could use this caching here, but I can't bacause the data is consantly changing. Sometimes you can't optimise your queries anymore...
Just another rainy day
Posts: 1
6 credits Members referred : 0
« Reply #4 on: Aug 01, 2007, 04:07:35 am »
Very nice article, and thanks for the clean code!
I had a little difficulty getting this to work until I changed the call to fileatime() to be filemtime(). That way you use the "modification time" instead of the "access time". I am on FreeBSD, not sure if that makes a difference.
cheers, James
Global Moderator Community Supporter?
Jedai Sword Master
Gender:
Posts: 6691
34714 credits Members referred : 374
I had a little difficulty getting this to work until I changed the call to fileatime() to be filemtime(). That way you use the "modification time" instead of the "access time". I am on FreeBSD, not sure if that makes a difference.
cheers, James
yeah I remember that some machines make a difference in this ...
Bill Cosby is my Father
Posts: 4
28 credits Members referred : 0
« Reply #7 on: Aug 09, 2007, 02:57:15 am »
very nice, thanks man, I'll c&p to my snippets file for a good look at, and use of later.
Where are my glasses?
Posts: 23
146 credits Members referred : 0
« Reply #8 on: Jan 03, 2009, 04:43:38 pm »
There are sites that will help YOU analyze your system, but don't let them do it for you. I've listed such a site below. They have links to volunteer sites that will help you clean your system, and somewhere along the line they will ask you to send them a log of what's going on with your system. They will use that to analyze your system and will give you advice based on that. That's safe. Don't let them have direct access to your system, however.
I wish I was an Oscar winner
Posts: 92
576 credits Members referred : 0
« Reply #9 on: Apr 14, 2011, 09:32:01 pm »
Will it help search engines to cache it?
I crack Photoshop!
Posts: 3
18 credits Members referred : 0
« Reply #10 on: Apr 22, 2011, 10:36:50 am »
I liked the idea
Cyberpunk Wannabe
Posts: 37
230 credits Members referred : 0
« Reply #11 on: May 02, 2011, 01:03:45 pm »
Thanks but there are smaller scripts for php caching
Novice Spammer
Posts: 102
652 credits Members referred : 0
« Reply #12 on: Jul 12, 2011, 05:34:35 pm »
I believe this is only for BSD founded os. If you use the get access to time on windows it will give you the last time somebody read the file
I wish I was an Oscar winner
Posts: 90
580 credits Members referred : 0
« Reply #13 on: Aug 23, 2011, 09:02:07 am »
Good idea. can be useful . will check it
Sandwich Artist
Posts: 25
174 credits Members referred : 0
« Reply #14 on: Aug 26, 2011, 07:20:16 am »
Very useful idea.. i like this.. i will check it.
Cyberpunk Wannabe
Posts: 41
300 credits Members referred : 0
« Reply #15 on: Sep 27, 2011, 08:31:56 am »
Also keep in mind most PHP accelerators/caches need a persistent PHP connection on the server. Most shared hosts use suPHP, which provides protection for their clients. suPHP also creates new PHP instances on every call apache makes, rending APC completely useless.
Cyberpunk Wannabe
Posts: 36
234 credits Members referred : 0
« Reply #16 on: Oct 15, 2011, 07:40:50 pm »
verything works fine and then for some reason the php caching stops and goes to regular compiling.
« Last Edit: Oct 15, 2011, 09:33:47 pm by Nikolas »
Bill Cosby is my Father
Posts: 4
24 credits Members referred : 0
« Reply #17 on: Nov 13, 2011, 11:27:31 am »
Alternative PHP Cache is a free, open source (PHP license) framework that optimizes PHP intermediate code and caches data and compiled code from the PHP bytecode compiler in shared memory. APC is quickly becoming the de-facto standard PHP caching mechanism as it will be included built-in to the core of PHP starting with PHP 5.4.
Spy Agent
Gender:
Posts: 111
690 credits Members referred : 0
« Reply #18 on: Nov 28, 2011, 05:43:48 am »
I liked the idea........ i will definitely check it.
Where are my glasses?
Posts: 21
130 credits Members referred : 0
« Reply #19 on: Jan 30, 2012, 11:29:42 pm »
Very nice article!
Trackback URI for this entry : http://www.webdigity.com/trackback.php?topic=862