A Universal Caching Algorithm for PHP using Memcached
Here is an elegant way to use the same caching logic for all function calls which should have a cache. With the proliferation of 3rd party APIs I was quite happy to find a way to address them all with a single mechanism.
function expensive_third_party_call( $param1, $param2 ) {
// universal caching algorithm header
$result = memcached_retrieve( __FUNCTION__ . serialize(func_get_args()) ) ;
if( $result!==null ) {
return $result ;
}
// this is where the third party call actually happens, if we are hit the cache missed
$to_return = /* some super complex and time consuming logic, throw in a couple of web calls*/ ;
// universal caching algorithm footer
memcached_store( __FUNCTION__ . serialize(func_get_args()), $to_return, CACHE_TIMEOUT ) ;
return $to_return ;
}
////////// helper functions bellow //////////
$m = false ;
function memcached_retrieve( $key ) {
global $m ;
$new_key = md5( $key ) ;
if( $m===false ) {
$m = new Memcached() ;
$m->addServer( 'localhost', 11211 ) ;
}
$temp = $m->get( $new_key ) ;
$result_code = $m->getResultCode() ;
if( $result_code==Memcached::RES_SUCCESS ) {
return $temp ;
} else if( $result_code==Memcached::RES_NOTFOUND ) {
return null ;
} else {
echo "error: can't retrieve memcached key {$key} with result_code {$result_code}" ;
}
return null ;
}
function memcached_store( $key, $data, $timeout ) {
global $m ;
$new_key = md5( $key ) ;
if( $m===false ) {
$m = new Memcached() ;
$m->addServer( 'localhost', 11211 ) ;
}
// a little heavy handed but we use null to represent that nothing was found in the cache so we can't have this be the data
if( $data===null ) {
$data = false ;
}
$m->set( $new_key, $data, $timeout ) ;
$result_code = $m->getResultCode() ;
if( $result_code!==Memcached::RES_SUCCESS ) {
echo "error: can't store memcached key {$key} with result_code {$result_code}" ;
return false ;
} else {
return true ;
}
return false ;
}
Requirements
- apt-get install memcached php-memcached
- make sure to define CACHE_TIMEOUT
Functioning principle
Using PHP’s awareness of the current function it is in along with the parameters which are passed to it, we derive a unique key which is used so store and retrieve from the cache.
Feature feature feature draw feature feature
Since the success of the Mandala maker, I’ve been pumping out a ton of features, improvements and bug fixes. They are too numerous to list but a few stand out.
- Collaborative editing using websockets for drawing mandalas with multiple people on the same session.
- Drawing without mandalas, there are only so many Mandalas one can collaboratively draw and so I created http://draw.akrin.com which leverages all the Mandalagaba goodness for drawing and removes the mandala specific layer.
- Read only mode guided by artists who like to livestream their drawing, I created a read-only mode to the collaboration. This way, people can watch but not participate.
- An iOS app was born
- High resolution renders are possible for $2, the charge helps with server costs and makes it a bit fairer if one was going to make money using the tool.
- Not visible but noteworthy nonetheless, an intricate server strategy was put in place to alleviate future waves, load balancing had to be built from scratch because of the collaboration layer.
- many, many, many other little things 🙂
In terms of use, while the initial tsunami is dead, the project was picked up by artists and educators. I can’t post all all the pictures for privacy but I can’t tell you how awesome it feels to receive pictures like these:
Kids enjoying a Mandala making lab somewhere in China
Artist Peter Draws created more amazing work:
The mandala maker was deployed on big touch screens which turned it into a more social activity much like arcade games.
Here’s draw.akrin.com: Click to pop out.




