A. File Cache

When dealing with dynamically formed data from a database or a service. It's probably ideal to cache the results. Eden comes with three ways to cache. The first one is called File Caching which involves saving the data to a file.

Figure 1. Creating a cache manager
$cache = eden('cache','path/to/cache/folder');

The figure above, simply sets the folder where cache files can be found. It's important to set permissions appropiately before using this class.

Apply chmod -R 775 to your cache folder on your server to prevent permission errors.

Seting Data

Once you have your cache manager set, we can now start saving data to the cache folder. The figure below shows how simple saving data is.

Figure 2. Saving Data to Cache
$cache->set('test', 'test.php', 'something data');

In Figure 2, the first argument is the name of your cache. This can be anything from a simple string to an entire datbase query. We just need to make sure it's unique. The second parameter is the name of the file to save the data. We allowed the ability to name files in the case you just want to access this file directly for other purposes. The last argument is the data you want to save. When this is called a key.php file will be generated in your cache folder if none exists as well as your cache data. That key file stores cache names to data file correlation. It's possible to manually control this file as well.

You can cache all PHP data types.

Getting Data

We also simplified retrieving data in the cache manager. Figure 3 shows how simple this is.

Figure 3. Simple data retrieval
$test = $cache->get('test');

So now that we understand all the main methods of the cache manager. Let's show how we can form a simple cache process.

Figure 4. Simple Cache Example
$time = $cache->getCreated('test'); //get the last time this was cached
$span = time() - 3600; 				//the time now minus 1 hour
if($time > $span) {					//if the last time this was cached is greater the the span
	$test = $cache->get('test');	//we should just get the cached object
} else {							//else we should rebuild that cache object
	$test = 'something data '.time();
	$cache->set('test', 'test.php', $test);
}

//either way echo test
echo $test;

Figure 4 shows that we are using a cache object called test which is set to rebuild every hour. When using cache with a database object, it's as simple as extending and overwriting the database class. Figure 5 shows how this can easily be done.

Figure 5. Setting up a Database Cache
class Custom_Mysql extends Eden_Mysql {
	public function query($query, array $binds = array()) {
		//if the query is an insert/update/delete
		if(strpos(strtolower($query), 'insert into') === 0 
		|| strpos(strtolower($query), 'update') === 0
		|| strpos(strtolower($query), 'delete from') === 0) {
			//get the table name
			$table = str_replace('insert into ', '', strtolower($query));
			$table = str_replace('update ', '', $table);
			$table = str_replace('delete from ', '', $table);
			list($table, $trash) = explode(' ', $table, 2);
			
			//get all the cache keys
			$keys = $this->_cache->getKeys();
			
			//invalidate all selects that use this table
			foreach($keys as $key) {
				if(strpos(strtolower($key), 'from '.$table) !== false 
				|| strpos(strtolower($key), 'join '.$table) !== false) {
					$this->_cache->remove($key);
				}
			}
		}
		
		//if it is an insert/update/delete
		if(strpos(strtolower($query), 'select') !== 0) {
			//just run it, because we only want to cache selects
			return parent::query($query, $binds);
		}
		
		//if we are here then it means the query is a select
		
		//check the cache, if it exists
		if($this->_cache->keyExists((string) $query)) {
			//return it.
			return $this->_cache->get((string) $query);
		}
		
		//run the query as normal
		$results = parent::query($query, $binds);
		
		//then cache the results
		$this->_cache->set((string) $query, time().'-'.front()->uid(), $results);
		$this->_results[(string) $query] = $results;
		
		return $results;
	}
}

//Replace Eden_Mysql with this class
eden('route')->getClass()->route('Eden_Mysql', 'Custom_Mysql');

So what we did was extend Eden's MySQL class and overwrote the query() method. If your not familiar with Eden's database classes, all methods and database classes eventually call this method in the end. This means this cache modification will now work for all MySQL related functionality. A more enterprise level caching system is called Memcache. We'll cover this in our next section, B. Memcache.


© 2012 Openovate Labs. All rights reserved.