繁体   English   中英

在取消链接之前,PHP已锁定文件

[英]PHP Lock on file before unlink

我想等待所有进程读取PHP中的某个文件,方法是对该文件获取排他锁,然后删除(取消链接)该文件。 这涉及诸如个人资料图片之类的文件,用户可以删除或更改这些文件。 文件名将类似于用户ID。

我的代码:

//Obtain lock
$file = fopen("path/to/file", "r"); //(I'm not sure which mode to use here btw)
flock($file, LOCK_EX);

//Delete file
unlink("path/to/file");

第3行等待所有锁释放,这很好,但是unlink函数会引发错误: Warning: unlink(path/to/file): Resource temporarily unavailable in path/to/script on line xx

为了防止这种情况,我可以在调用unlink之前释放锁定,但这意味着另一个进程可能再次锁定文件,这将导致相同的错误。

我的问题是:

  1. 是否可以在不释放锁的情况下删除PHP中的文件? 也就是说,没有其他进程尝试同时使用文件的风险。

如果不:

  1. Windows完全可能吗? Unix怎么样?
  2. 我应该将此数据库包含在我的数据库中,而是锁定数据库中的行,还是有更好的方法?
  3. 我可以看到的另一个选择是重复这段代码,包括在调用unlink之前释放锁定,直到unlink成功为止,但这似乎有些混乱,对吗?

嘿,两年后,我也在为此而苦苦挣扎。 似乎有些愚蠢,您在尝试重命名或取消链接时无法获得文件的排他锁,或者至少没有文档来执行此操作。

一种解决方案是打开文件进行写入,获取排他锁,使用ftruncate清除文件内容,将其关闭然后取消链接。 从文件读取时,可以检查大小以确保文件包含内容。

删除时(未测试的代码):

$fh = fopen('yourfile.txt', 'c'); // 'w' mode truncates file, you don't want to do that yet!
flock($fh, LOCK_EX); // blocking, but you can use LOCK_EX | LOCK_NB for nonblocking and a loop + sleep(1) for a timeout
ftruncate($fh, 0); // truncate file to 0 length
fclose($fh);
unlink('yourfile.txt');

阅读时(未经测试的代码):

if (!file_exists('yourfile.txt') || filesize('yourfile.txt') <= 0) {
  print 'nah.jpg, must be dELeTeD :O';
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM