备份下代码
<?php namespace Lib\Library; use Closure; use Exception; /** * 文件锁 * 1.阻塞,进程加锁时发现其他进程已经加锁会一直阻塞等待,一直等到可以加锁成功,然后去执行业务代码 * 2.非阻塞,进程加锁时发现其他进程已经加锁直接返回,不会执行业务代码 * 3.注意Erp默认Session驱动为文件,本身请求已经存Session锁机制,所以测试非阻塞时请修改Session驱动为Redis * @package Lib\Library */ class FileLock { /** * 锁文件位置 * @var string */ private $file; /** * 锁文件句柄 * @var */ private $fileHandle; /** * 构造函数 * @param string $name 锁名称 * @throws Exception */ public function __construct($name = 'lock') { //初始化文件 $path = RUNTIME_PATH . 'Lock' . DIRECTORY_SEPARATOR; $this->file = $path . md5($name); if (!is_dir($path)) { if (!mkdir($path, 0777, true)) { throw new Exception('文件锁目录创建失败,请检查目录' . $path . '是否可写'); } } if (!file_exists($this->file)) { if (file_put_contents($this->file, '')) { throw new Exception('文件锁创建失败,请检查文件' . $this->file . '是否可写'); } } } /** * 加锁 * @param bool $block * @return bool */ public function lock($block = true) { $this->fileHandle = fopen($this->file, 'r'); $is_flock = $block ? flock($this->fileHandle, LOCK_EX) : flock($this->fileHandle, LOCK_EX | LOCK_NB); if (!$is_flock) { fclose($this->fileHandle); } return $is_flock; } /** * 释放 */ public function release() { if (!$this->fileHandle) { return false; } $unlock = flock($this->fileHandle, LOCK_UN); if ($unlock) { fclose($this->fileHandle); $this->fileHandle = null; } return $unlock; } /** * 加锁执行 * @param Closure $func 执行闭包函数 * @param bool $block 是否阻塞 * @return mixed 闭包函数的返回值 */ public function lockToExecute($func, $block = true) { $is_flock = $this->lock($block); $call_back = null; if ($is_flock) { $call_back = $func(); $this->release(); } return $call_back; } }