<?php /* --------------------------------------------------- Class: cacher Author: Adam Flatau of Reflect Studios Date: 03/14/08 Description: Class to mange both APC and memcache data transactions. --------------------------------------------------*/ class cacher{ /* ------------------------------------ Our first two set of arrays we will be defined in our config. To hold the server IPs and ports for the memcache servers. We will split the servers with : to check for port. serverArray[0] = localhost serverArray[1] = server2:1337 ------------------------------------*/ public $serverArray = array(); // we will define an array of servers in the config for our memcache public $memCache; // reserved for our memcache object if needed function __construct($memcache = 0){ global $memServerArray; if($memcache){ $this->memCache = new Memcache; $this->serverArray = $memServerArray; } } function memConnect($server = null, $pCon = null){ /* -------------------------------------- Our function to connect to the memcache server. We will go ahead and get our server IP address from our serverArray and port from portArray. If failure to connecting to server, it will try next sever in the array. If pcon is set to true, it will then open up a pressitent connection. If server is supllied it will connect with that server. We Will check to see if the server is an IP or index value for the serverArray. --------------------------------------*/ if($this->memCache) { if($server) { if(is_numeric($server)) { // index from serverArray $server = $this->serverArray[$server]; $port = null; }else{ // use custom IP , we will do an // explode to see if there is a port $server = split(':', $server); if(!isset($server[1])) $port = '11211'; else $port = $server[1]; } if($pCon){ $memcon = @$this->memCache->pconnect($server[0], $port); }else{ $memcon = @$this->memCache->connect($server[0], $port); } if($memcon) { return array(1, 1); } else { $this->p_error(0, 'There was an error while trying to connect to the memcache server IP:' . $server[0] . ' Port:' . $port); return array(0, 'Error with connection to memcache server'); } }else{ // ok grab one from the serverArray // we will first start from index 0 $server = split(':',$this->serverArray[0]); if(!isset($server[1])) $port = '11211'; else $port = $server[1]; if($pCon) $conType = 'pconnect'; else $conType = 'connect'; $memcon = @$this->memCache->$conType($server[0],$port); if($memcon){ return array(1,1); }else{ // error with connection to server. // prcocess this error and move to next. $this->p_error(0,"Error with connecting to memcache server:" . $server[0] . " port:" . $port); $x = 1; while($x <= count($this->serverArray)){ $server = split(':',$this->serverArray[$x]); if(!isset($server[1])) $port = '11211'; else $port = $server[1]; $memcon = @$this->memCache->$conType($server[0],$port); if($memcon) $x = count($this->serverArray) +1; else $x++; } if($memcon){ return array(1,1); }else{ $this->p_error(0,'Error with connecting to memcache server, exhausted all servers trough serverArray'); return array(0,"Error with connecting to memcach server, exhausted all attempts"); } } } }else{ // memcache object was not created in the constructor return array(0,"Memcache object was not created in the constructor"); } } function add($key,$value,$engine,$ttl = null, $memPCon = null , $memServer = null,$memFlag = false){ /* -------------------------------------- Function to add data to our cache. Do a switch on engine to add our data to the right cache. ------------------------------------*/ switch($engine){ case "APC": // add to our APC memory cache system. $add = apc_add($key,$value,$ttl); if($add){ return array(1,1); }else{ $this->p_error(0,"Error with storing data into the APC system. Key:" . $key); return array(0,"Error with storing data into the APC cache system"); } break; case "MEM": // add to our memcache memory cache system. if($memServer){ $memcon = $this->memConnect($memServer,$memPCon); if($memcon[0]){ $add = $this->memCache->add($key,$value,$memFlag,$ttl); if($add){ return array(1,1); }else{ $this->p_error(0,"Error with storing data into the memcache system. Key:" . $key); return array(0,"Error with storing data into the memcache system"); } }else{ return array(0,$memcon[1]); } }else{ $memcon = $this->memConnect(); if($memcon[0]){ $add = $this->memCache->add($key,$value,$memFlag,$ttl); if($add){ return array(1,1); }else{ $this->p_error(0,"Error with storing datainto the memcache system. Key:" . $key); return array(0,"Error with storing data into the memcache system"); } }else{ return array(0,$memcon[1]); } } break; case "APCMEM": // add to both memcache and APC caching systems. $errs = array(); // APC $APCadd = apc_add($key,$value,$ttl); if(!$APCadd){ $this->p_error(0,"Error with storing data into the APC system. Key:" . $key); $errs[] = 'Error with storing data into the APC cache system'; } //memcache if($memServer){ $memcon = $this->memConnect($memServer,$memPCon); if($memcon[0]){ $add = $this->memCache->add($key,$value,$memFlag,$ttl); if(!$add){ $this->p_error(0,"Error with storing data into the memcache system. Key:" . $key); $errs[] = "Error with storing data into the memcache system"; } }else{ $errs[] = $memcon[1]; } }else{ $memcon = $this->memConnect(); if($memcon[0]){ $add = $this->memCache->add($key,$value,$memFlag,$ttl); if(!$add){ $this->p_error(0,"Error with storing datainto the memcache system. Key:" . $key); $errs[] = "Error with storing data into the memcache system"; } }else{ $errs[] = $memcon[1]; } } // check to make sure there are no errors if(empty($errs)) return array(1,1); else return array(0,$errs); break; default: return array(0,"Unkown memory engine supllied"); break; } } function get($key, $engine, $memServer = null){ /* ---------------------------------------- Function to get dat from system defined cached. --------------------------------------*/ switch($engine){ case "APC": $fetch = apc_fetch($key); if($fetch){ return array(1,$fetch); }else{ //$this->p_error(0,"Error with getting data from cache. Key:" . $key); return array(0,"Error with getting data from cache"); } break; case "MEM": $memcon = $this->memConnect($memServer); if($memcon[0]){ $get = $this->memCache->get($key); if($get){ return array(1,$get); }else{ return array(0,"Error with getting data from cache"); } }else{ return array(0,$memcon[1]); } break; case "APCMEM": $errs = array(); //APC $APCData = apc_fetch($key); if(!$APCData){ $errs[] = 'Error with getting data from APC system cache'; } //memcache $memcon = $this->memConnect($memServer); if($memcon[0]){ $memData = $this->memCache->get($key); if(!$memData){ $errs[] = 'Error with getting data from memcache system'; } }else{ $errs[] = 'Error with connecting to memcache server'; } if(empty($errs)) return array(1,$APCData,$memData); else return array(0,$errs); break; default: return array(0,"Unkown memory engine supllied"); break; } } function replace($key, $value, $engine, $ttl = null, $memFlag = false, $memPCon = null, $memServer = null){ /* -------------------------------------------- Function to replace data that is currently stored into the system cache. To update items in the system cache with out reseting the ttl/ expirartion time. We will do the following. Inside the array of data or data its self. Simply put a time stamp + the ttl value inside. Parse out the the time and do simple math to figure out time reaming to set as new TTL/ expirartion time. --------------------------------------------*/ switch($engine){ case "APC": $store = apc_store($key,$value,$ttl); if($store){ return array(1,1); }else{ $this->p_error(0,"Error with updating APC system cache on key:" . $key); return array(0,"Error with updating system cache"); } break; case "MEM": $memcon = $this->memConnect($memServer, $memPCon); if($memcon[0]){ $replace = $this->memCache->replace($key,$value,$memFlag,$ttl); if($replace){ return array(1,1); }else{ $this->p_error(0,"Error with updating memcache system cache on key:" . $key); return array(0,"Error with updating system cache"); } }else{ return array(0,$memcon[1]); } break; case "APCMEM": $errs = array(); //APC $store = apc_store($key,$value,$ttl); if(!$store){ $errs[] = 'Error with updating APC system cache'; } //memcache $memcon = $this->memConnect($memServer, $memPCon); if($memcon[0]){ $replace = $this->memCache->replace($key,$value,$memFlag,$ttl); if(!$replace){ $errs[] = 'Error with updating memcache system cache'; } }else{ $errs[] = $memcon[1]; } if(empty($errs)) return array(1,1); else return array(0,$errs); break; default: return array(0,"Unkown memory engine supllied"); break; } } function delete($key,$engine,$memServer = null){ switch($engine){ case "APC": $del = apc_delete($key); if($del) return true; else return false; break; case "MEM": $memcon = $this->memConnect($memServer); if($memcon[0]){ $del = $this->memCache->delete($key); if($del) return true; else return false; }else{ return false; } break; case "APCMEM": $errs = array(); //APC $del = apc_delete($key); if(!$del) $errs[] = 'Error with removing key from APC'; //memcahce $memcon = $this->memConnect($memServer); if($memcon[0]){ $del = $this->memCache->delete($key); if(!$del) $errs[] = 'Error with removing key from memcache'; } if(empty($errs)) return true; else return false; break; default: return array(0,"Unkown memory engine supllied"); break; } } function flushIt(){ /* -------------------------------------------- Function to removoe the entire system cache from ALL servers. --------------------------------------------*/ // first flush out our APC @apc_clear_cache(); if($this->memCache){ for($i=0;$i<=count($this->serverArray);$i++){ $memcon = $this->memConnect($this->serverArray[$i]); if($memcon) $this->memCache->flush(); $this->memCache->close(); } } } function prepTTL($ttl){ /* -------------------------------------------- Function to take a current ttl value and compare to system time , to figure out a new ttl value for updating/replacing data in cache for example. 1207100600 stored ttl value 1207100200 current system time 400 new TTL value --------------------------------------------*/ $curTime = time(); $newTTL = $ttl - $curTime; return $newTTL; } function p_error($err,$sql = ""){ switch($err){ case 0: // custom error $err = "0 - " . date("m-j-y") . " Custom Error: " . $sql; write_error("CACHER",$err); break; default: break; } } function __destruct(){ if($this->memCache){ $this->memCache->close(); } } }?>