這篇文章主要介紹了php的memcache類的使用方法(memcache隊列),需要的朋友可以參考下
memcacheQueue.class.php 代碼如下: <?php /** * PHP memcache 隊列類 * @author LKK/lianq.net * @version 0.3 * @修改說明: * 1.放棄了之前的AB面輪值思路,使用類似數組的構造,重寫了此類. * 2.隊列默認先進先出,但增加了反向讀取功能. * 3.感謝網友FoxHunter提出的寶貴意見. * @example: * $obj = new memcacheQueue('duilie'); * $obj->add('1asdf'); * $obj->getQueueLength(); * $obj->read(10); * $obj->get(8); */ class memcacheQueue{ public static $client; //memcache客戶端連接 public $access; //隊列是否可更新 private $expire; //過期時間,秒,1~2592000,即30天內 private $sleepTime; //等待解鎖時間,微秒 private $queueName; //隊列名稱,唯一值 private $retryNum; //重試次數,= 10 * 理論並發數 public $currentHead; //當前隊首值 public $currentTail; //當前隊尾值 const MAXNUM = 20000; //最大隊列數,建議上限10K const HEAD_KEY = '_lkkQueueHead_'; //隊列首kye const TAIL_KEY = '_lkkQueueTail_'; //隊列尾key const VALU_KEY = '_lkkQueueValu_'; //隊列值key const LOCK_KEY = '_lkkQueueLock_'; //隊列鎖key /** * 構造函數 * @param string $queueName 隊列名稱 * @param int $expire 過期時間 * @param array $config memcache配置 * * @return <type> */ public function __construct($queueName ='',$expire=0,$config =''){ if(empty($config)){ self::$client = memcache_pconnect('127.0.0.1',11211); }elseif(is_array($config)){//array('host'=>'127.0.0.1','port'=>'11211') self::$client = memcache_pconnect($config['host'],$config['port']); }elseif(is_string($config)){//"127.0.0.1:11211" $tmp = explode(':',$config); $conf['host'] = isset($tmp[0]) ? $tmp[0] : '127.0.0.1'; $conf['port'] = isset($tmp[1]) ? $tmp[1] : '11211'; self::$client = memcache_pconnect($conf['host'],$conf['port']); } if(!self::$client) return false; ignore_user_abort(true);//當客戶斷開連接,允許繼續執行 set_time_limit(0);//取消腳本執行延時上限 $this->access = false; $this->sleepTime = 1000; $expire = empty($expire) ? 3600 : intval($expire)+1; $this->expire = $expire; $this->queueName = $queueName; $this->retryNum = 1000; $this->head_key = $this->queueName . self::HEAD_KEY; $this->tail_key = $this->queueName . self::TAIL_KEY; $this->lock_key = $this->queueName . self::LOCK_KEY; $this->_initSetHeadNTail(); } /** * 初始化設置隊列首尾值 */ private function _initSetHeadNTail(){ //當前隊列首的數值 $this->currentHead = memcache_get(self::$client, $this->head_key); if($this->currentHead === false) $this->currentHead =0; //當前隊列尾的數值 $this->currentTail = memcache_get(self::$client, $this->tail_key); if($this->currentTail === false) $this->currentTail =0; } /** * 當取出元素時,改變隊列首的數值 * @param int $step 步長值 */ private function _changeHead($step=1){ $this->currentHead += $step; memcache_set(self::$client, $this->head_key,$this->currentHead,false,$this->expire); } /** * 當添加元素時,改變隊列尾的數值 * @param int $step 步長值 * @param bool $reverse 是否反向 * @return null */ private function _changeTail($step=1, $reverse =false){ if(!$reverse){ $this->currentTail += $step; }else{ $this->currentTail -= $step; } memcache_set(self::$client, $this->tail_key,$this->currentTail,false,$this->expire); } /** * 隊列是否為空 * @return bool */ private function _isEmpty(){ return (bool)($this->currentHead === $this->currentTail); } /** * 隊列是否已滿 * @return bool */ private function _isFull(){ $len = $this->currentTail - $this->currentHead; return (bool)($len === self::MAXNUM); } /** * 隊列加鎖 */ private function _getLock(){ if($this->access === false){ while(!memcache_add(self::$client, $this->lock_key, 1, false, $this->expire) ){ usleep($this->sleepTime); @$i++; if($i > $this->retryNum){//嘗試等待N次 return false; break; } } $this->_initSetHeadNTail(); return $this->access = true; } return $this->access; } /** * 隊列解鎖 */ private function _unLock(){ memcache_delete(self::$client, $this->lock_key, 0); $this->access = false; } /** * 獲取當前隊列的長度 * 該長度為理論長度,某些元素由於過期失效而丟失,真實長度<=該長度 * @return int */ public function getQueueLength(){ $this->_initSetHeadNTail(); return intval($this->currentTail - $this->currentHead); } /** * 添加隊列數據 * @param void $data 要添加的數據 * @return bool */ public function add($data){ if(!$this->_getLock()) return false; if($this->_isFull()){ $this->_unLock(); return false; } $value_key = $this->queueName . self::VALU_KEY . strval($this->currentTail +1); $result = memcache_set(self::$client, $value_key, $data, MEMCACHE_COMPRESSED, $this->expire); if($result){ $this->_changeTail(); } $this->_unLock(); return $result; } /** * 讀取隊列數據 * @param int $length 要讀取的長度(反向讀取使用負數) * @return array */ public function read($length=0){ if(!is_numeric($length)) return false; $this->_initSetHeadNTail(); if($this->_isEmpty()){ return false; } if(empty($length)) $length = self::MAXNUM;//默認所有 $keyArr = array(); if($length >0){//正向讀取(從隊列首向隊列尾) $tmpMin = $this->currentHead; $tmpMax = $tmpMin + $length; for($i= $tmpMin; $i<=$tmpMax; $i++){ $keyArr[] = $this->queueName . self::VALU_KEY . $i; } }else{//反向讀取(從隊列尾向隊列首) $tmpMax = $this->currentTail; $tmpMin = $tmpMax + $length; for($i= $tmpMax; $i >$tmpMin; $i--){ $keyArr[] = $this->queueName . self::VALU_KEY . $i; } } $result = @memcache_get(self::$client, $keyArr); return $result; } /** * 取出隊列數據 * @param int $length 要取出的長度(反向讀取使用負數) * @return array */ public function get($length=0){ if(!is_numeric($length)) return false; if(!$this->_getLock()) return false; if($this->_isEmpty()){ $this->_unLock(); return false; } if(empty($length)) $length = self::MAXNUM;//默認所有 $length = intval($length); $keyArr = array(); if($length >0){//正向讀取(從隊列首向隊列尾) $tmpMin = $this->currentHead; $tmpMax = $tmpMin + $length; for($i= $tmpMin; $i<=$tmpMax; $i++){ $keyArr[] = $this->queueName . self::VALU_KEY . $i; } $this->_changeHead($length); }else{//反向讀取(從隊列尾向隊列首) $tmpMax = $this->currentTail; $tmpMin = $tmpMax + $length; for($i= $tmpMax; $i >$tmpMin; $i--){ $keyArr[] = $this->queueName . self::VALU_KEY . $i; } $this->_changeTail(abs($length), true); } $result = @memcache_get(self::$client, $keyArr); foreach($keyArr as $v){//取出之後刪除 @memcache_delete(self::$client, $v, 0); } $this->_unLock(); return $result; } /** * 清空隊列 */ public function clear(){ if(!$this->_getLock()) return false; if($this->_isEmpty()){ $this->_unLock(); return false; } $tmpMin = $this->currentHead--; $tmpMax = $this->currentTail++; for($i= $tmpMin; $i<=$tmpMax; $i++){ $tmpKey = $this->queueName . self::VALU_KEY . $i; @memcache_delete(self::$client, $tmpKey, 0); } $this->currentTail = $this->currentHead = 0; memcache_set(self::$client, $this->head_key,$this->currentHead,false,$this->expire); memcache_set(self::$client, $this->tail_key,$this->currentTail,false,$this->expire); $this->_unLock(); } /* * 清除所有memcache緩存數據 */ public function memFlush(){ memcache_flush(self::$client); } }//end class