php实现文件锁
文件锁的基本概念
文件锁(File Locking)是一种机制,用于控制多个进程或线程对同一文件的并发访问,避免数据竞争或损坏。PHP 通过 flock() 函数实现文件锁,支持共享锁(LOCK_SH)和独占锁(LOCK_EX)。

使用 flock() 实现文件锁
flock() 是 PHP 内置函数,语法如下:
bool flock(resource $handle, int $operation [, int &$wouldblock ])
$handle:文件资源句柄,需通过fopen()打开。$operation:锁类型,常用值:LOCK_SH:共享锁(读锁),其他进程可读但不可写。LOCK_EX:独占锁(写锁),其他进程不可读写。LOCK_UN:释放锁。LOCK_NB:非阻塞模式(结合LOCK_SH或LOCK_EX使用)。
示例代码
独占锁(写入时加锁)
$file = 'test.txt';
$handle = fopen($file, 'a+');
if (flock($handle, LOCK_EX)) { // 获取独占锁
fwrite($handle, "Data to write\n");
flock($handle, LOCK_UN); // 释放锁
} else {
echo "Could not lock the file!";
}
fclose($handle);
共享锁(读取时加锁)
$handle = fopen('test.txt', 'r');
if (flock($handle, LOCK_SH)) { // 获取共享锁
$content = fread($handle, filesize('test.txt'));
flock($handle, LOCK_UN); // 释放锁
echo $content;
}
fclose($handle);
非阻塞模式
$handle = fopen('test.txt', 'a+');
if (flock($handle, LOCK_EX | LOCK_NB)) { // 非阻塞独占锁
fwrite($handle, "Non-blocking write\n");
flock($handle, LOCK_UN);
} else {
echo "File is locked by another process.";
}
fclose($handle);
注意事项
- 文件句柄必须有效:确保
fopen()成功打开文件后再调用flock()。 - 锁的释放:操作完成后必须调用
LOCK_UN释放锁,否则其他进程会阻塞。 - NFS 文件系统:
flock()在 NFS 上可能不可靠,需考虑其他方案(如数据库锁)。 - 脚本结束自动释放:PHP 脚本执行结束时未释放的锁会被系统自动清除。
替代方案
对于高并发场景,可以考虑以下替代方案:
- 数据库锁(如 MySQL 的
SELECT ... FOR UPDATE)。 - 使用缓存系统(如 Redis 的
SETNX实现分布式锁)。






