cache-memcached.php

Memcached driver for my cache library
git clone git://git.finwo.net/lib/cache-memcached.php
Log | Files | Refs | README

Memcached.php (2821B)


      1 <?php
      2 
      3 namespace Finwo\Cache;
      4 
      5 /**
      6  * Implements memcached
      7  * Handles refreshing in a server-friendly way
      8  */
      9 class Memcached extends Cache
     10 {
     11     /**
     12      * @var \Memcached
     13      */
     14     protected $memcached;
     15 
     16     /**
     17      * @var string
     18      */
     19     protected $server = '127.0.0.1';
     20 
     21     /**
     22      * @var int
     23      */
     24     protected $port = 11211;
     25 
     26     /**
     27      * @return \Memcached
     28      */
     29     protected function getMemcached()
     30     {
     31         if (null === $this->memcached) {
     32             $this->memcached = new \Memcached();
     33             $this->memcached->addServer($this->server, $this->port);
     34         }
     35 
     36         return $this->memcached;
     37     }
     38 
     39     public function __construct($options = array())
     40     {
     41         // Override default options
     42         foreach($options as $key => $value) {
     43             if (isset($this->{$key})) {
     44                 $this->{$key} = $value;
     45             }
     46         }
     47     }
     48 
     49     /**
     50      * {@inheritdoc}
     51      */
     52     public function fetch($key = '', $ttl = 30)
     53     {
     54         // Generate seperate keys for fetching
     55         $key_lock = \md5(\sprintf("%s_lock", $key));
     56         $key_data = \md5(\sprintf("%s_data", $key));
     57         $key_ttl  = \md5(\sprintf("%s_ttl",  $key));
     58 
     59         // Fetch memcached object
     60         $memcached = $this->getMemcached();
     61 
     62         // Fetch data
     63         $data_data = $memcached->get($key_data);
     64 
     65         // Return data if the current TTL is still valid
     66         if ($memcached->get($key_ttl)) {
     67             return $data_data;
     68         }
     69 
     70         // Return data if we're already "refreshing"
     71         if ($memcached->get($key_lock)) {
     72             return $data_data;
     73         }
     74 
     75         // Mark we're refreshing for ttl/10
     76         // Also give it 2 seconds, because some operations take time
     77         $memcached->add($key_lock, 'Hello World', max(2,$ttl/10));
     78 
     79         // And return that we don't have recent data
     80         return false;
     81     }
     82 
     83     /**
     84      * {@inheritdoc}
     85      */
     86     public function store($key = '', $value, $ttl = 30)
     87     {
     88         // Generate seperate keys for storing
     89         $key_data = \md5(\sprintf("%s_data", $key));
     90         $key_ttl  = \md5(\sprintf("%s_ttl",  $key));
     91 
     92         // Pre-generate time
     93         $time_data = \max(3600, $ttl*10);
     94         if ($ttl === 0) {
     95             $time_data = 0;
     96         }
     97 
     98         // Fetch memcached object
     99         $memcached = $this->getMemcached();
    100 
    101         // Store data
    102         if($memcached->get($key_data)) {
    103             $memcached->replace($key_data, $value, $time_data);
    104         } else {
    105             $memcached->add($key_data, $value, $time_data);
    106         }
    107 
    108         // Store TTL
    109         $memcached->add($key_ttl, 'Hello World', $ttl);
    110 
    111         // Return ourselves
    112         return $this;
    113     }
    114 
    115     /**
    116      * (@inheritdoc}
    117      */
    118     public function supported()
    119     {
    120         return class_exists('Memcached');
    121     }
    122 }