Created
May 11, 2021 09:27
-
-
Save imbyc/f009e6ccaf171d1145de063957fd3e91 to your computer and use it in GitHub Desktop.
[PHP 并发下安全读写文件函数] https://mkblog.cn/1831/ 使用flock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @link http://kodcloud.com/ | |
* @author warlee | e-mail:[email protected] | |
* @copyright warlee 2014.(Shanghai)Co.,Ltd | |
* @license http://kodcloud.com/tools/license/license.txt | |
*/ | |
/** | |
* 安全读取文件,避免并发下读取数据为空 | |
* | |
* @param $file 要读取的文件路径 | |
* @param $timeout 读取超时时间 | |
* @return 读取到的文件内容 | false - 读取失败 | |
*/ | |
function file_read_safe($file, $timeout = 5) { | |
if (!$file || !file_exists($file)) return false; | |
$fp = @fopen($file, 'r'); | |
if (!$fp) return false; | |
$startTime = microtime(true); | |
// 在指定时间内完成对文件的独占锁定 | |
do { | |
$locked = flock($fp, LOCK_EX | LOCK_NB); | |
if (!$locked) { | |
usleep(mt_rand(1, 50) * 1000); // 随机等待1~50ms再试 | |
} | |
} | |
while ((!$locked) && ((microtime(true) - $startTime) < $timeout)); | |
if ($locked && filesize($file) >= 0) { | |
$result = @fread($fp, filesize($file)); | |
flock($fp, LOCK_UN); | |
fclose($fp); | |
if (filesize($file) == 0) { | |
return ''; | |
} | |
return $result; | |
} else { | |
flock($fp, LOCK_UN); | |
fclose($fp); | |
return false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* 安全写文件,避免并发下写入数据为空 | |
* | |
* @param $file 要写入的文件路径 | |
* @param $buffer 要写入的文件二进制流(文件内容) | |
* @param $timeout 写入超时时间 | |
* @return 写入的字符数 | false - 写入失败 | |
*/ | |
function file_write_safe($file, $buffer, $timeout = 5) { | |
clearstatcache(); | |
if (strlen($file) == 0 || !$file) return false; | |
// 文件不存在则创建 | |
if (!file_exists($file)) { | |
@file_put_contents($file, ''); | |
} | |
if(!is_writeable($file)) return false; // 不可写 | |
// 在指定时间内完成对文件的独占锁定 | |
$fp = fopen($file, 'r+'); | |
$startTime = microtime(true); | |
do { | |
$locked = flock($fp, LOCK_EX); | |
if (!$locked) { | |
usleep(mt_rand(1, 50) * 1000); // 随机等待1~50ms再试 | |
} | |
} | |
while ((!$locked) && ((microtime(true) - $startTime) < $timeout)); | |
if ($locked) { | |
$tempFile = $file.'.temp'; | |
$result = file_put_contents($tempFile, $buffer, LOCK_EX); | |
if (!$result || !file_exists($tempFile)) { | |
flock($fp, LOCK_UN); | |
fclose($fp); | |
return false; | |
} | |
@unlink($tempFile); | |
ftruncate($fp, 0); | |
rewind($fp); | |
$result = fwrite($fp, $buffer); | |
flock($fp, LOCK_UN); | |
fclose($fp); | |
clearstatcache(); | |
return $result; | |
} else { | |
flock($fp, LOCK_UN); | |
fclose($fp); | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment