提供生產級的 PHP 檔案鎖定函數庫,支援阻塞/非阻塞模式、自動清理鎖檔、資源釋放,適用於多行程環境下的關鍵區段保護、排程任務防重複執行等場景。
function lock_thisfile($tmpFileStr, $locktype = false) {
// $locktype: false=非阻塞(LOCK_EX|LOCK_NB), true=阻塞(LOCK_EX)
if ($locktype === false) $locktype = LOCK_EX | LOCK_NB;
$lockfp = @fopen($tmpFileStr . ".lock", "w");
if (!$lockfp) return false;
$can_write = @flock($lockfp, $locktype);
if ($can_write) return $lockfp; // 回傳檔案指標供解鎖使用
// 取得鎖失敗:清理資源
@fclose($lockfp);
@unlink($tmpFileStr . ".lock");
return false;
}
function unlock_thisfile($fp, $tmpFileStr) {
@flock($fp, LOCK_UN); // 釋放鎖
@fclose($fp); // 關閉檔案指標
@unlink($tmpFileStr . ".lock"); // 刪除鎖檔
}
<?php
$tmpFileStr = "/tmp/mylock.loc";
// 阻塞模式:等待直到取得鎖
$lockhandle = lock_thisfile($tmpFileStr, true);
if ($lockhandle) {
// === 關鍵區段開始 ===
// 執行獨佔操作:寫入檔案、資料庫交易、API 呼叫等
// === 關鍵區段結束 ===
unlock_thisfile($lockhandle, $tmpFileStr);
} else {
echo "無法取得鎖,可能有其他行程正在執行";
}
?>
| 模式 | 第二參數 | flock 旗標 | 行為 |
|---|---|---|---|
| 非阻塞 | false (預設) | LOCK_EX | LOCK_NB | 立即回傳 false 若鎖被佔用 |
| 阻塞 | true | LOCK_EX | 等待直到取得鎖 |
/tmp 或專用目錄,避免權限問題。flock() 可能不可靠,需改用資料庫鎖或 Redis 分散式鎖。flock() 為強制鎖,行為與 Linux 建議鎖略有不同。將檔案鎖封裝為可重用函數,能有效簡化併發控制邏輯,提升系統穩定性。