A different approach to page caching

2007-09-11

A different approach to page caching, cache only one portion of your page using a simple php class.

Did you notice that on most websites after you log in, there is a "Welcome YourName" box or something like this ? Caching the entire page for such a website is absurd, because the page is different for each user.

So, you must use a different approach, cache only portions of the page. Portions that are common for all users, and that don't change often. In this way, you will save a lot of your server processing time and be able to serve more users without additional hardware costs.

Here is how I do it. I have impelemented a simple standalone php class, I will explain later how to use it, and how it works. For now this is the code

/*
   Cache class
    Copyright (C) 2007 CodeAssembly.com  

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses/
*/
class Cache
{
	private $file;
	private $hit;
	private $time;
	private $keep = false;

	public function __construct( $name, $time, $unique = null)
	{
		$this -> file = constant('CACHE_DIR') . $name . $unique ;//set cache file
		$this -> time = $time;
	}

	public function isCache()
	{
		if (isset( $this -> hit ))//on sequential calls don't recalculate
		{
			return $this -> hit;
		} else
		if ( file_exists( $this -> file ) ) //if file does not exist
		{
			if ( ( time() - filemtime( $this -> file ) ) > $this -> time )
			{
				$this -> hit = false;
				return false;
			} else
			{
				$this -> hit = true;
				return true;
			}
		} else
		{
			$this -> hit = false;
			return false;
		}
	}

	public function start()
	{
		if ( $this -> isCache() )
		{
			require( $this -> file );
			return false;
		} else
		{
			ob_start();
			return true;
		}

	}

	public function end()
	{
		if ( $this -> hit === false )
		{
			if ( $this -> keep === false)
			{
				if ( $f = fopen( $this -> file, "w+") )
				{
					if (flock($f , LOCK_EX))
					{ // do an exclusive lock
						echo $buf = ob_get_clean();
						fwrite($f,  $buf );
						flock($f, LOCK_UN);
						// release the lock
					} else
					{
						//echo "Couldn't lock the file !";
					}
				}
			} else require( $this -> file );
		}
	}

	public function reset()
	{
		return unlink( $this -> file );
	}

	public function keep()
	{
		$this -> keep = true;
	}
	
	static public function clear($interval)
	{
		
	}
}

And now, an example that shows how to use the class

/*
This is how to create a new instance the first parameter is the key of the cache, this must be unique for each section of your page, the second parameter is the cache timeout expressed in seconds and the last parameter is a unique id.
The purpose of the unique id,is that some pages have different content  based on a different id (usually a database unique key).This can be the article id or something similar.

This code i put in my controller
*/
$cache_section = new cache('cache_section_key', 86400, $page_id);
if (!$cache_section->isCache())//if cache expired
{
/*
Execute time consuming sql's here
*/
  $view -> article = $DB -> getRow('SELECT title,content FROM articles WHERE id = ?',$page_id);
}

/*
The 'start' method returns true if the cache expired
$cache_section->start()
The 'end' method outputs the cached data, or if the cached expired, it stores the cached data.
$cache_section ->end();

This part of the code i put in my view
*/


.
.
.
start())
{
   echo $this -> article -> title;
   echo $this -> article -> content;
}
$cache_section ->end();
?>
.
.

Share this with the world

Related

Comments

No comments at this time

Make yourself heard

Categories

Subscribe

All Posts

Php posts

All Comments

This post comments

© Copyright CodeAssembly

All code is licensed under GPL, unless otherwise noted