1. 程式人生 > >php對檔案鎖進行加鎖、解鎖

php對檔案鎖進行加鎖、解鎖

        在專案中,一般都用到日誌,如資料庫查詢日誌、訪問日誌、對外介面請求返回引數日誌,在處理日誌時簡單的寫法如下

$file = 'log.txt';
$fp = fopen($file, 'a+');
if(!is_writable($file)){
    die("The $file is not writable!");
}
fwrite($fp, 'here');
fclose($fp);

        但這種寫法是由瑕疵的,一個網站同一時間並不是只有一個使用者訪問的,在多個使用者同時訪問時,就會出現問題,也就是多個程序使用同一個資源時,前一個程序寫到一半後面的程序便開始寫了,因此最後生成的日誌就亂了。這種情況下,就用到鎖了,在檔案加鎖期間,其他程序是不會修改檔案的,只有當檔案解鎖時,才可以操作。寫法如下
$file = 'log.txt';
$fp = fopen($file, 'a+');
if(!is_writable($file)){
    exit("The $file is not writable!");
}
flock($fp, LOCK_EX);// 加鎖
fwrite($fp, 'here');
flock($fp, LOCK_UN);// 解鎖
fclose($fp);

        如果想測試下在檔案加鎖期間其他程序操作不了檔案的例子,可以用下面給出的demo
// log.php
$file = 'log.txt';
$fp = fopen($file, 'a+');
if(!is_writable($file)){
    exit("The $file is not writable!");
}
flock($fp, LOCK_EX);
fwrite($fp, 'here');
sleep(10);
flock($fp, LOCK_UN);
fclose($fp);

// test.php
$file = 'lock.txt';
$fp = fopen($file, 'a');
fwrite($fp, 'good'); // 在sleep期間寫不進去
fclose($fp);

// 或是直接使用下面的這個例子,發現在sleep期間列印是個空值
//var_dump(file_get_contents($file));
        測試時,先執行log.php,再執行test.php,會發現在sleep期間,test.php是執行達不到效果的。