flock() 函数将文件句柄作为其第一个参数,将锁定操作作为其第二个参数。文件句柄你已经知道了,操作很简单:LOCK_SH请求共享锁,LOCK_EX请求排他锁,LOCK_UN释放锁。如果文件锁被成功检索,则调用flock() 将返回true,如果失败则返回false。因此,例如,flock() 可以这样使用:
<?php
$fp = fopen( $filename,"w"); // open it for WRITING ("w")
if (flock($fp, LOCK_EX)) {
// do your file writes here
flock($fp, LOCK_UN); // unlock the file
} else {
// flock() returned false, no lock obtained
print "Could not lock $filename!\n";
}
?>
默认情况下,PHP 中的文件锁定机制自动使进程排队等待锁定。例如,将下一个脚本保存为flock.php:
<?php
$fp = fopen("foo.txt", "w");
if (flock($fp, LOCK_EX)) {
print "Got lock!\n";
sleep(10);
flock($fp, LOCK_UN);
}
?>
该脚本尝试锁定文件 foo.txt,因此您需要创建该文件。该脚本使用 LOCK_EX 锁定它,这意味着没有其他程序可以锁定该文件。获得锁后,脚本会休眠十秒钟,然后解锁文件并退出。如果由于另一个应用程序有锁而无法获得锁,则脚本会在flock() 调用中等待锁被释放,然后自行锁定并继续。
要对此进行测试,请打开两个命令提示符并运行脚本两次。第一个脚本运行将立即获得锁并打印“Got lock!”,然后休眠十秒钟。如果在第一个脚本处于休眠状态时启动第二个脚本,它将等待(“块”)调用 flock() 并等待第一个脚本完成。当第一个脚本完成时,第二个脚本将成功获取它的锁,打印出“Got lock!” 然后再睡十秒钟,直到它最终终止。
有时不希望您的脚本等待文件解锁,在这种情况下,您可以使用按位 OR 运算符 | 在第二个参数中添加一个额外选项。如果您使用普通的第二个参数传入 LOCK_NB ORed,PHP 在请求文件锁定时不会阻塞。这意味着如果文件锁不可用,flock() 将立即返回 false,而不是等待锁可用。
这是代码中的样子:
<?php
$fp = fopen("foo.txt", "w");
if (flock($fp, LOCK_EX | LOCK_NB)) {
echo "Got lock!\n";
sleep(10);
flock($fp, LOCK_UN);
} else {
print "Could not get lock!\n";
}
?>
这一次,第一个脚本将获取锁并打印“Got lock!”,而第二个脚本将无法获取锁,立即返回并打印“Could not get lock!”。