2024 年 PHP 日本研討會

clearstatcache

(PHP 4, PHP 5, PHP 7, PHP 8)

clearstatcache清除檔案狀態快取

說明

clearstatcache(布林值 $clear_realpath_cache = false, 字串 $filename = ""):

當您使用 stat()lstat() 或任何其他列於受影響函式列表(如下)中的函式時,PHP 會快取這些函式返回的資訊,以提供更快的效能。然而,在某些情況下,您可能需要清除快取的資訊。例如,如果在單個腳本中多次檢查同一個檔案,並且該檔案在腳本運行期間有可能被移除或更改,您可以選擇清除狀態快取。在這些情況下,您可以使用 clearstatcache() 函式來清除 PHP 快取的關於檔案的資訊。

您還應該注意,PHP 不會快取關於不存在檔案的資訊。因此,如果您對不存在的檔案調用 file_exists(),它會返回 false,直到您建立該檔案。如果您建立了該檔案,即使您之後刪除了該檔案,它也會返回 true。然而,unlink() 會自動清除快取。

注意事項:

此函式會快取關於特定檔案名的資訊,因此您只有在對同一個檔名執行多個操作,並且需要關於該特定檔案的資訊不被快取時,才需要調用 clearstatcache()

受影響的函式包括 stat()lstat()file_exists()is_writable()is_readable()is_executable()is_file()is_dir()is_link()filectime()fileatime()filemtime()fileinode()filegroup()fileowner()filesize()filetype()fileperms()

參數

clear_realpath_cache

是否*同時*清除 realpath 快取。

filename

僅清除特定檔案名的 realpath 快取;僅在 clear_realpath_cachetrue 時使用。

返回值

不返回任何值。

範例

範例 #1 clearstatcache() 範例

<?php
$file
= 'output_log.txt';

function
get_owner($file)
{
$stat = stat($file);
$user = posix_getpwuid($stat['uid']);
return
$user['name'];
}

$format = "UID @ %s: %s\n";

printf($format, date('r'), get_owner($file));

chown($file, 'ross');
printf($format, date('r'), get_owner($file));

clearstatcache();
printf($format, date('r'), get_owner($file));
?>

上述範例會輸出類似以下的內容:

UID @ Sun, 12 Oct 2008 20:48:28 +0100: root
UID @ Sun, 12 Oct 2008 20:48:28 +0100: root
UID @ Sun, 12 Oct 2008 20:48:28 +0100: ross

新增註釋

使用者貢獻的註釋 6 則註釋

matt_m at me dot com
13 年前
如果您正在對遠端檔案執行 file_exists(),例如:

<?php
if (file_exists("ftp://ftp.example.com/somefile"))
?>

則 unlink() 不會清除快取。在這種情況下,即使您成功執行了 unlink(),也必須呼叫 clearstatcache()。

<?php
unlink
("ftp://ftp.example.com/somefile");
clearstatcache();
?>

然後 file_exists() 才會正確地返回 false。
msaladna at apisnetworks dot com
4 年前
clearstatcache() 並不會正規化路徑。 clearstatcache(true, "/a/b/c") 和 clearstatcache(true, "/a/b//c") 的效果不同。
vechenjivot at gmail dot com
4 年前
雖然沒有文件記載,但 clearstatcache() 似乎只會清除呼叫它的行程的快取。我有兩個同時執行的 PHP 腳本,第一個腳本呼叫了 clearstatcache(),但第二個腳本仍然會發生死結,除非我在第二個腳本中也呼叫 clearstatcache()

script1
<?php
touch
('system.lock');
...
unlink('system.lock');
clearstatcache(); // 應該由 unlink 完成?
?>

script2
<?php
while (is_file('system.lock')) {
sleep(1);
clearstatcache(); // 如果沒有這行,script 2 將會永遠死結!
}
?>

我也找到了這個頁面,它導向了相同的結論
https://stackoverflow.com/questions/9251237/clearstatcache-include-path-sessions
David Spector
5 年前
請注意,這個函式只會影響檔案的中繼資料。然而,所有 PHP 檔案系統函式也會自行快取實際的檔案內容。您可以在 PHP.ini 中使用 "realpath_cache_size = 0" 指令來停用內容快取。預設的內容快取逾期時間為 120 秒。

在開發工作和某些類型的應用程式中,內容快取並不是一個好主意,因為您的程式碼可能會從您剛更改內容的檔案中讀取舊資料。

注意:這與瀏覽器通常針對所有 GET 請求(大多數網路存取)進行的快取不同,除非 HTTP 標頭覆寫它。它也與 Apache 伺服器的選用快取機制不同。
bj at wjblack dot com
9 年前
只是為了讓這一點更明顯(也讓搜尋引擎更容易找到)

如果您在 PHP 之外進行任何檔案操作(例如透過 system() 呼叫),您可能需要在對檔案/目錄/任何東西進行進一步測試之前清除 stat 快取。例如

<?php
// is_dir() 會強制執行 stat 呼叫,因此快取會被填入
if( is_dir($foo) ) {
system("rm -rf " . escapeshellarg($foo));
if(
is_dir($foo) ) {
// ...即使 rm 成功,結果仍然會是 true,因為它只是
// 從快取讀取,而不是重新執行 stat()
}
}
?>

在 system 呼叫後使用 clearstatcache() 可以解決這個問題(但清除 stat 快取會稍微降低效能 :-()。
Gabriel
5 年前
$filename 參數的定義讓你以為它只接受檔名,但即使你提供路徑加上檔名,它也能正常運作。

這點應該要更清楚地說明。
To Top