首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP is_file 與 file_exists 關鍵差異:快取機制導致的檔案檢測陷阱

     編輯:PHP 綜合知識

為什麼 is_file 無法取代 file_exists?

許多開發者以為 is_file() 和 file_exists() 只是功能重疊,實際上它們在快取機制上有本質差異,這在高併發或檔案頻繁變動的場景下會導致嚴重 Bug。

實測驗證:is_file 的快取行為

<?php
$filename = 'test.txt';

// 確保測試檔案存在
file_put_contents($filename, 'test');

// 第一次檢測
if (is_file($filename)) {
    echo "$filename exists!\n";
} else {
    echo "$filename no exists!\n";
}

// 模擬 10 秒後檔案被刪除
sleep(10);  // 在此期間手動刪除 test.txt

// 第二次檢測
if (is_file($filename)) {
    echo "$filename exists!\n";
} else {
    echo "$filename no exists!\n";
}

輸出結果

test.txt exists!
test.txt exists!  <-- 錯誤!檔案已刪除但仍回傳 true

根本原因:PHP 內部 stat 快取

  • is_file():第一次呼叫時會將檔案屬性(stat 資訊)快取在記憶體中,同一腳本執行期間再次呼叫同檔名時直接讀取快取,不存取磁碟
  • file_exists():無快取機制,每次呼叫都會即時存取檔案系統

改用 file_exists() 的正確結果

test.txt exists!
test.txt no exists!  <-- 正確反映檔案已刪除

解決方案:clearstatcache()

若必須使用 is_file()、is_dir()、filesize() 等依賴 stat 快取的函數,在檔案可能被外部修改的情況下,請手動清除快取:

clearstatcache(); // 清除所有 stat 快取
// 或 PHP 5.3+ 針對特定檔案清除
clearstatcache(true, $filename);

函數快取行為對照表

函數有快取適用場景
file_exists()❌ 否即時檢查檔案是否存在
is_file()✅ 是效能敏感、確定檔案不會外部變動
is_dir()✅ 是效能敏感、確定目錄不會外部變動
filesize()✅ 是效能敏感、確定檔案大小不會變動
filemtime()✅ 是效能敏感、確定修改時間不會變動

最佳實踐建議

  1. 預設使用 file_exists() 進行存在性檢查,避免快取陷阱
  2. 效能關鍵路徑且確定無外部變動時,可用 is_file() 並搭配 clearstatcache()
  3. 長時間執行的腳本(如 daemon、queue worker)定期呼叫 clearstatcache()
  4. 分散式系統中檔案由其他節點管理時,務必使用 file_exists()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved