在php中對於文件的操作我們多半會使用文件鎖定來為避免多用戶同時操作時沖突了,下面小編與大家一起來測試一下文件鎖定獨占操作一些實例分析。
flock – 輕便的咨詢文件鎖定
flock()函數原型
bool flock ( int handle, int operation [, int &wouldblock] )
PHP 支持以咨詢方式(也就是說所有訪問程序必須使用同一方式鎖定, 否則它不會工作)鎖定全部文件的一種輕便方法
operation 可以是以下值之一:
要取得共享鎖定(讀取的程序),將 operation 設為 LOCK_SH(PHP 4.0.1 以前的版本設置為 1)。
要取得獨占鎖定(寫入的程序),將 operation 設為 LOCK_EX(PHP 4.0.1 以前的版本中設置為 2)。
要釋放鎖定(無論共享或獨占),將 operation 設為 LOCK_UN(PHP 4.0.1 以前的版本中設置為 3)。
如果不希望 flock() 在鎖定時堵塞,則給 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中設置為 4)。
flock() 允許執行一個簡單的可以在任何平台中使用的讀取/寫入模型(包括大部分的 Unix 派生版和甚至是 Windows)。如果鎖定會堵塞的話(EWOULDBLOCK 錯誤碼情況下),可選的第三個參數會被設置為 TRUE。鎖定操作也可以被 fclose() 釋放(代碼執行完畢時也會自動調用)。
如果成功則返回 TRUE,失敗則返回 FALSE。
注意:
在 Windows 下 flock() 將會強制執行。flock() 操作的 handle 必須是一個已經打開的文件指針。
由於 flock() 需要一個文件指針, 因此可能不得不用一個特殊的鎖定文件來保護打算通過寫模式打開的文件的訪問(在 fopen() 函數中加入 “w” 或 “w+”)。
flock() 不能用於 NFS 以及其它一些網絡文件系統。flock() 不支持舊的文件系統,如 FAT 以及它的派生系統。因此,此環境下總是返回 FALSE(尤其是對 Windows)詳細資料查看自己操作系統的文檔。
在部分操作系統中 flock() 以進程級實現。當用一個多線程服務器 API(比如 ISAPI)時,可能不可以依靠 flock() 來保護文件,因為運行於同一服務器實例中其它並行線程的 PHP 腳本可以對該文件進行處理。
獨占測試:
下列兩個文件都差不多,區別在於寫入的東西不一樣,先運行a.php文件,保持不關閉狀態,接著運行b.php文件,然後去查看寫入的文件內容,你會發現b.php文件的內容並沒有寫入成功!
代碼如下 復制代碼<?php
// a.php
if ( ! ($f = @fopen("flock.log","ab"))) exit;
flock($f, LOCK_EX);
while(TRUE)
{
fwrite($f, "an");
}
?>
<?php
// b.php
if ( ! ($f = @fopen("flock.log","ab"))) exit;
flock($f, LOCK_EX);
while(TRUE)
{
fwrite($f, "bn");
}
?>
比如我們有兩個文件,如下。
flocka.php
代碼如下 復制代碼 $file = 'temp.txt';
flockb.php
代碼如下 復制代碼 $file = 'temp.txt';先運行flocka.php,然後馬上運行flockb.php。
結果:
11111111
22222222
22222222
22222222
22222222
22222222
11111111
11111111
11111111
11111111
說明不加文件鎖時,兩個文件會同時對txt文件進行寫入操作。
下面修改一下兩個php文件的代碼。
flocka.php
代碼如下 復制代碼 $file = 'temp.txt';
flockb.php
同樣先運行flocka.php,然後馬上運行flockb.php。
會發現在flocka.php運行結束前,flockb.php一直處於等待狀態,只有當flocka.php運行結束後,flockb.php才會繼續執行。
輸出結果:
11111111
11111111
11111111
11111111
11111111
22222222
22222222
22222222
22222222
22222222
另外,在執行flock時,文件鎖會自動釋放