memcache){ $this->memcache = @memcache_connect($host, $port); } else { @memcache_add_server($this->memcache, $host, $port); } } if ($this->memcache){ $this->ok = true; } } public function get($key){ if (!$this->ok){ return null; } $a = memcache_get($this->memcache, _CACHE_NAMESPACE . $key); // maybe_unserialize if (is_array($a)){ return @unserialize($a[0]); } else { return $a; } } public function set($key, $value, $ttl = null){ if (!$this->ok){ return null; } // maybe_serialize if (is_object($value) or is_array($value) or is_null($value)){ $value = array(serialize($value)); } $flag = strlen(is_array($value) ? $value[0] : $value)>16000 ? MEMCACHE_COMPRESSED : 0; return is_null($ttl) ? memcache_set($this->memcache, _CACHE_NAMESPACE . $key, $value) : memcache_set($this->memcache, _CACHE_NAMESPACE . $key, $value, $flag, $ttl); } public function exists($key){ if (!$this->ok){ return null; } return memcache_get($this->memcache, _CACHE_NAMESPACE . $key)!==FALSE; } public function del($key){ if (!$this->ok){ return null; } return memcache_delete($this->memcache, _CACHE_NAMESPACE . $key, 0); } public function inc($key, $value = null, $ttl = null){ if (!$this->ok){ return null; } // set if not exists @memcache_add($this->memcache, _CACHE_NAMESPACE . $key, 0, $ttl); if (!isset($value)){ $value = 1; } return memcache_increment($this->memcache, _CACHE_NAMESPACE . $key, $value); } public function dec($key, $value = null, $ttl = null){ if (!$this->ok){ return null; } // set if not exists memcache_add($this->memcache, _CACHE_NAMESPACE . $key, 0, $ttl); if (!isset($value)){ $value = 1; } return memcache_decrement($this->memcache, _CACHE_NAMESPACE . $key, $value); } public function lock($key, /* private */ $unlock = false){ static $locks = array(); if (!$this->ok){ return null; } /* unlock */ if ($unlock){ unset($locks[$key]); $this->del('lock::' . $key); } /* lock */ else { # si on l'a deja, ok if (isset($locks[$key])){ return true; } # sinon s'il existe, on attend qu'il se libere $wait = 0; while ($this->exists('lock::' . $key)){ if ($wait++<_LOCK_MAX){ sleep(1); } else { return false; } } # ... puis on le pose # attention inc() renvoie parfois false (??) if ($this->inc('lock::' . $key, 1, _LOCK_MAX)<=1){ $this->set('lock::' . $key, 2, _LOCK_MAX); $locks[$key] = true; register_shutdown_function(array($this, 'unlock'), $key); return true; } return false; } } public function unlock($key){ if (!$this->ok){ return null; } $this->lock($key, true); } public function size(){ return false; } public function purge(){ return false; } }