flower_svr/class/gzhq_lock.class.php
2021-06-11 16:09:56 +08:00

175 lines
4.6 KiB
PHP

<?php
/**锁操作
* Created by gzhq.
* User: 252378189@qq.com
* Date: 2018/3/18
* Time: 20:18
*/
class gzhq_lock{
const LOCK_TYPE_DB = 'SQLLock';
const LOCK_TYPE_FILE = 'FileLock';
const LOCK_TYPE_MEMCACHE = 'MemcacheLock';
private $_lock = false;
private static $_supportLocks = array('FileLock', 'SQLLock', 'MemcacheLock','RedisLock');
public function __construct($type, $options = array()){
if(false == empty($type)) {
$this->createLock($type, $options);
}
}
public function createLock($type, $options=array()){
if(false == in_array($type, self::$_supportLocks)){
throw new Exception("not support lock of ${type}");
}else{
$this->_lock = new $type($options);
}
}
public function getLock($key, $timeout = in_lock::EXPIRE){
if (false == $this->_lock instanceof in_lock) {
throw new Exception('false == $this->_lock instanceof ILock');
}
$this->_lock->getLock($key, $timeout);
}
public function unLock($key){
if (false == $this->_lock instanceof in_lock) {
throw new Exception('false == $this->_lock instanceof ILock');
}
$this->_lock->unLock($key);
}
}
//必须实现的接口
interface in_lock{
const EXPIRE = 5;
public function getLock($key, $timeout=self::EXPIRE);
public function unLock($key);
}
//创建文件锁
class FileLock implements in_lock{
private $_fp;
private $_lockPath;
//创建锁
/*
* $options = '';//文件存放路径
*/
public function __construct($options){
if (isset($options) && is_dir($options)) {
$this->_lockPath = $options.'/';
}else{
$this->_lockPath = WEBPATH_DIR.'/cache/';
}
}
public function getLock($key, $timeout=self::EXPIRE){
$file = md5($key);
$tmp_mypath = $this->_lockPath .$file.'.lock';
$this->_fp = fopen($tmp_mypath,"w+");
if ($this->_fp === false) {
return false;
}
$waitime = 10;
$totalWaitime = 0;
$timeout *=1000000;
while (!flock($this->_fp,LOCK_EX | LOCK_NB)) { // 加锁
$totalWaitime +=$waitime;
if ($totalWaitime > $timeout) { // 超时逻辑
fclose($this->_fp);
return false;
}
usleep($waitime);
}
return true;
}
public function unLock($key){
flock($this->_fp,LOCK_UN);
fclose($this->_fp);
return true;
}
}
//创建mysql锁
class SQLLock implements in_lock{
private $_db;
//创建锁
/*
* $options='';//数据库连接
*/
public function __construct($options){
$this->_db = $options;
}
public function getLock($key, $timeout=self::EXPIRE){
$sql = "SELECT GET_LOCK('KEY".$key."', '".$timeout."')";
$res = $this->_db->query($sql);
return $res;
}
public function unLock($key){
$sql = "SELECT RELEASE_LOCK('KEY".$key."')";
return $this->_db->query($sql);
}
}
//创建Memcache锁
class MemcacheLock implements in_lock{
private $memcache;
//创建锁
/*
* $options='';//Memcache连接
*/
public function __construct($options){
$this->memcache = $options;
}
public function getLock($key,$timeout=self::EXPIRE){
$waitime = 10;
$totalWaitime = 0;
$time = $timeout*1000000;
while (false == $this->memcache->add("KEY".$key, 1, $timeout)) {
usleep($waitime);
$totalWaitime += $waitime;
if ($totalWaitime >= $time){
return false;
}
}
return true;
}
public function unLock($key){
$this->memcache->delete("KEY".$key);
return true;
}
}
//创建redis锁
class RedisLock implements in_lock{
private $redis;
//创建锁
/*
* $options='';//Redis连接
*/
public function __construct($options){
$this->redis = $options;
}
public function getLock($key, $timeout=self::EXPIRE){
$waitime = 10;//延时多久检查
$totalWaitime = 0;//当前等了多久
$time = $timeout*1000000;//把超时时间从毫秒改为微秒
while(false==$this->redis->psetex("KEY".$key,$time,1)){
usleep($waitime);
$totalWaitime += $waitime;
if ($totalWaitime >= $time){
return false;
}
}
return true;
}
public function unLock($key){
$this->redis->delete("KEY".$key);
return true;
}
}