1 <?php 2 /** 3 * Class redis_lock 4 * 5 * 单机redis 分布式锁 6 */ 7 8 class redis_lock 9 { 10 public $redis; 11 12 public function __construct() //连接Redis服务器 13 { 14 $this->redis = new \redis(); 15 $this->redis->connect('127.0.0.1', 6379); 16 // $this->redis->auth('123456'); 17 // $this->redis->select(12); 18 } 19 20 /** 21 * 单台Redis设置锁 22 * 23 * @param string $key 24 * @param int $expire 25 * @return bool 26 */ 27 public function setLock($key, $expire = 10) 28 { 29 $res = $this->check_key($key); 30 if (!$res) { 31 return false; 32 } 33 $res = $this->check_expire($expire); 34 if (!$res) { 35 return false; 36 } 37 $res = $this->redis->set('Redis:Lock:' . $key, time() + $expire, ['nx', 'ex' => $expire]); 38 if (!$res) { 39 return false; 40 } 41 return true; 42 } 43 44 /** 45 * 校验有效期 46 * 47 * @param mixed $expire 48 * @return int 49 */ 50 public function check_expire($expire) 51 { 52 if (!is_numeric($expire)) { 53 return false; 54 } 55 return true; 56 } 57 58 /** 59 * 校验$key 60 * 61 * @param mixed $key 62 * @return bool 63 */ 64 public function check_key($key) 65 { 66 if (!is_string($key) && !is_int($key)) { 67 return false; 68 } 69 //允许数字、英文字符、下划线、英文冒号 70 preg_match('/^[\w\:]*+$/', $key, $p_key); 71 if (!isset($p_key[0]) || $p_key[0] != $key) { 72 return false; 73 } 74 return true; 75 } 76 77 /** 78 * 单台Redis设备锁,如果不能进入将等待 79 * 80 * @param string $key 81 * @param int $expire 82 * @param int $wait_seconds 83 * @return bool 84 */ 85 public function setLockAndWait($key, $expire = 10, $wait_seconds = 10) 86 { 87 /*如果是webserver,并且session服务器是文件或者memcache,最好加上这一行 88 也可以用session_commit(),解除session锁。如果session服务器是redis,就不用了*/ 89 session_write_close(); 90 $time = time(); 91 $wait_time = $time + $wait_seconds; 92 while (true) { 93 $res = $this->setLock($key, $expire); 94 if ($res) { 95 return $res; 96 } 97 if ($time >= $wait_time) { 98 return false; 99 } 100 usleep(500); //等待微妙数 101 } 102 } 103 104 /** 105 * 单台Redis删除锁 106 * 107 * @param string $key 108 * @return bool 109 */ 110 public function delLock($key) 111 { 112 $res = $this->redis->del($key); 113 if ($res === false) { 114 return false; 115 } 116 return true; 117 } 118 } 119 120 $redis = new redis_lock(); 121 $res = $redis->setLock('lock'); 122 $redis->delLock('lock'); 123 var_dump($res);125 ?>