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.

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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.