簡體   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