PHP Conference Japan 2024

filemtime

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

filemtime取得檔案修改時間

說明

filemtime(字串 $filename): 整數|false

這個函式會返回檔案的資料區塊正在被寫入的時間,也就是檔案內容被更改的時間。

參數

filename

檔案的路徑。

返回值

返回檔案最後修改的時間,如果失敗則返回 false。時間以 Unix 時間戳記的形式返回,適用於 date() 函式。

錯誤/例外

失敗時,會發出 E_WARNING 警告。

範例

範例 #1 filemtime() 範例

<?php
// 輸出例如 somefile.txt 最後修改時間:2002 年 12 月 29 日 22:16:23。

$filename = 'somefile.txt';
if (
file_exists($filename)) {
echo
"$filename 最後修改時間: " . date ("F d Y H:i:s.", filemtime($filename));
}
?>

注意事項

注意:

請注意,時間解析度可能因檔案系統而異。

注意此函式的結果會被快取。詳情請參閱 clearstatcache()

提示

從 PHP 5.0.0 開始,此函式也可以與「某些」URL 包裝器一起使用。請參閱 支援的協定和包裝器 以確定哪些包裝器支援 stat() 系列函式。

另請參閱

  • filectime() - 取得檔案的 inode 變更時間
  • stat() - 提供有關檔案的資訊
  • touch() - 設定檔案的存取和修改時間
  • getlastmod() - 取得頁面最後修改時間

新增註釋

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

geeks at geekman dot info
16 年前
這是一個處理瀏覽器快取非常方便的函式。例如,假設您有一個樣式表,並且您希望確保每個人都擁有最新版本。您可以每次編輯時都重新命名它,但那樣會很麻煩。您可以改用以下方法:

<?php
echo '<link rel="stylesheet" type="text/css" href="style.css?' . filemtime('style.css') . '" />';
?>

範例輸出

<link rel="stylesheet" type="text/css" href="style.css?1203291283" />

藉由在樣式表網址附加 GET 值(UNIX 時間戳記),您可以讓瀏覽器認為樣式表是動態的,如此一來,每當修改日期變更時,它就會重新載入樣式表。
paranoid at dds dot nl
21 年前
要取得目錄的最後修改時間,您可以使用以下程式碼:

<pre>
$getLastModDir = filemtime("/path/to/directory/.");
</pre>

請注意最後一個點,它需要將目錄視為檔案才能實際取得其最後修改日期。

當您只想在網站首頁顯示一則「上次更新」訊息,同時又想將網站所有檔案都納入考量時,這個方法就派上用場了。

此致,
Frank Keijzers
habazi at yahoo dot com
19 年前
「這(不一定)正確,目錄的修改時間將會是目錄中最後一個檔案*建立*的時間(而不是其子目錄中的時間)。」

這也(不一定)正確。在 *nix 系統中,時間戳記可以獨立設定。例如,指令「touch directory」會更新目錄的時間戳記,而不會建立檔案。

刪除檔案也會更新目錄的時間戳記。
solarijj at gmail dot com
17 年前
要取得遠端檔案的修改日期,您可以使用 notepad at codewalker dot com 提供的良好函式(經由 dma05 at web dot de 和 madsen at lillesvin dot net 改進)。

但現在您可以使用 stream_get_meta_data (PHP>4.3.0) 更輕鬆地達成相同的結果。

然而,如果發生重新導向,可能會產生問題。在這種情況下,伺服器 HTTP 回應不包含 Last-Modified 標頭,但會有一個 Location 標頭指示檔案的位置。以下函式會處理任何重新導向,即使是多次重新導向,以便您找到想要取得其最後修改日期的實際檔案。

hih,
JJS.

<?php

// 取得遠端檔案的最後修改日期(回傳 Unix 時間戳記)
function GetRemoteLastModified( $uri )
{
// 預設值
$unixtime = 0;

$fp = fopen( $uri, "r" );
if( !
$fp ) {return;}

$MetaData = stream_get_meta_data( $fp );

foreach(
$MetaData['wrapper_data'] as $response )
{
// 狀況:重新導向
if( substr( strtolower($response), 0, 10 ) == 'location: ' )
{
$newUri = substr( $response, 10 );
fclose( $fp );
return
GetRemoteLastModified( $newUri );
}
// 狀況:最後修改時間
elseif( substr( strtolower($response), 0, 15 ) == 'last-modified: ' )
{
$unixtime = strtotime( substr($response, 15) );
break;
}
}
fclose( $fp );
return
$unixtime;
}
?>
MarkAgius at markagius dot co dot uk
3 年前
filemtime(..) 函式僅適用於您伺服器上的檔案。
$T=filesize("index.php"); // 可以正常運作。
$T=filesize("/public_html/dir/index.php"); // 可以正常運作。

但以下程式碼將無法運作。
$T=filesize("https://mydomain.com/dir/index.php"); // 無法運作。即使是同一個網域,但使用網址的方式也無效。
$T=filesize("https://otherdomain.com/dir/index.php"); // 不同網域,無法運作。

要取得其他網站的檔案日期,請嘗試以下程式碼
(注意:時區可能是格林威治標準時間 (GMT),而不是您的本地時區)

$T = getFileDate("https://mydomain.com/dir/index.php");
$T = getFileDate("https://otherdomain.com/dir/index.php");

function getFileDate($filePath){
// 與 filemtime(..) 相同,但也適用於遠端檔案。
// 例如:印出日期 date("j/m/Y, g:i:sa (e)",getFileDate("https://abc.com/file.jpg"));
// 若找不到檔案,則回傳 -307756800 (1960/04/01)
$ret = -(3562 * 24 * 60 * 60); // 1960/04/01 3562 = 距離 1970/01/01 的秒數

$ch = curl_init($filePath);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 嘗試取得檔案修改日期
curl_setopt($ch, CURLOPT_FILETIME, true);
$result = curl_exec($ch);
if ($result === false) {
die(curl_error($ch));
return $ret;
}

$ret = curl_getinfo($ch, CURLINFO_FILETIME);
curl_close($ch);

return $ret;
}
erelsgl at gmail dot com
14 年前
更簡潔但較不嚴謹的快取寫法

<?php
$cache_file
= '快取檔案的 URI';
$cache_life = '120'; // 快取時間,單位為秒

$filemtime = @filemtime($cache_file); // 若檔案不存在,則回傳 FALSE
if (!$filemtime || (time() - $filemtime >= $cache_life)) {
ob_start();
resource_consuming_function();
file_put_contents($cache_file, ob_get_flush());
} else {
readfile($cache_file);
}
?>
myselfasunder at gmail dot XYZ dot com
14 年前
由於 Windows 系統下的 `filemtime()` 會呼叫 Windows 的 `stat()` 函式,而該函式會實作 DST(根據此錯誤回報:http://bugs.php.net/bug.php?id=40568),因此在 Windows 系統下使用 `filemtime()` 會產生一個深層的問題。系統判斷檔案時間是否為日光節約時間 (DST) 時,會被目前系統時間是否為日光節約時間所混淆。

這是針對這個惱人錯誤的修正方法。

<?php
函式 GetCorrectMTime($filePath)
{

$time = filemtime($filePath);

$isDST = (date('I', $time) == 1);
$systemDST = (date('I') == 1);

$adjustment = 0;

if(
$isDST == false && $systemDST == true)
$adjustment = 3600;

else if(
$isDST == true && $systemDST == false)
$adjustment = -3600;

else
$adjustment = 0;

return (
$time + $adjustment);
}
?>

Dustin Oprea
匿名者
19 年前
以下的評論指出

「當使用這個函式來取得目錄的修改日期時,
它會回傳該目錄中最後被修改的檔案的日期。」

這(未必)正確,目錄的修改時間會是目錄中最後被*建立*的檔案的時間(而不是它子目錄中的檔案)。
adam at roomvoter dot com
20 年前
先前那段允許您刪除所有超過兩週的檔案的程式碼使用了函式 (filemtime) - 它會檢查檔案的原始建立日期(與檔案系統無關)。您*可能*想要使用 filectime() - 它會查看檔案在*您的*檔案系統上最後被更改的時間。

if (is_dir("$path") )
{
$handle=opendir($path);
while (false!==($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$Diff = (time() - filectime("$path/$file"))/60/60/24;
if ($Diff > 14) unlink("$path/$file");

}
}
closedir($handle);
}
_michael
14 年前
在 Windows 上測試時,我注意到 filemtime 的精度只有 1 秒。

因此,如果您使用 clearstatcache() 和 filemtime() 來檢查檔案是否已被修改,它可能無法偵測到更改。修改只需要在不到一秒內發生。

(我在 Windows XP 上的 Apache 遇到這個問題。)
notepad at codewalkers dot com
19 年前
我需要能夠抓取遠端網站上圖片的修改時間。以下是在 Joe Ferris 的幫助下得到的解決方案。

<?php

函數 filemtime_remote($uri)
{
$uri = parse_url($uri);
$handle = @fsockopen($uri['host'],80);
if( !
$handle)
return
0;

fputs($handle,"GET $uri[path] HTTP/1.1\r\nHost: $uri[host]\r\n\r\n");
$result = 0;
while( !
feof($handle))
{
$line = fgets($handle,1024);
if( !
trim($line))
break;

$col = strpos($line,':');
if(
$col !== false)
{
$header = trim(substr($line,0,$col));
$value = trim(substr($line,$col+1));
if(
strtolower($header) == 'last-modified')
{
$result = strtotime($value);
break;
}
}
}
fclose($handle);
return
$result;
}
// 顯示遠端檔案的最後修改時間: echo filemtime_remote('http://www.somesite.com/someimage.jpg');

?>
wookie at at no-way dot org
21 年前
另一個好用的小工具:取得目錄中檔案的最新修改時間。如果將 $doRecursive 參數設為 true,它甚至可以遞迴處理子目錄。基於我在這個網站上看到的某個檔案/目錄列表函數。 ;)

函數 mostRecentModifiedFileTime($dirName, $doRecursive) {
$d = dir($dirName);
$lastModified = 0;
while($entry = $d->read()) {
if ($entry != "." && $entry != "..") {
if (!is_dir($dirName."/".$entry)) {
$currentModified = filemtime($dirName."/".$entry);
} else if ($doRecursive && is_dir($dirName."/".$entry)) {
$currentModified = mostRecentModifiedFileTime($dirName."/".$entry, true);
}
if ($currentModified > $lastModified){
$lastModified = $currentModified;
}
}
}
$d->close();
return $lastModified;
}
Will Davies Vasconcelos
13 年前
這是一個方便的腳本,用於建立一個 csv 檔案,其中包含指定資料夾中檔案的名稱和檔案新增日期

<?php
header
("Pragma: public");
header("Cache-Control: private");
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=age-of-files.csv");

$result = array();
$handle = opendir(".");
while (
$datei = readdir($handle))
{
if ((
$datei != '.') && ($datei != '..'))
{
$file = "./".$datei;
if (!
is_dir($file))
$result[] = $file;
}
}
closedir($handle);
foreach(
$result as $r)
if (
file_exists($r))
echo
substr($r,2).",".date ("m/d/Y", filemtime($r))."\r\n";
?>
Benan Tumkaya (benantumkaya at yahoo)
18 年前
這是一個小巧但方便的腳本,您可以用它來查找伺服器中哪些檔案是在您指定的日期/時間之後修改的。此腳本將遞迴地遍歷指定目錄中的所有資料夾,並顯示修改後的檔案及其最後修改的日期/時間...

//從這裡開始
//在此處放置您要搜尋的目錄。如果您想搜尋整個網域,請放置 /
$dir='/';

//將您要比較的日期以 YYYY-mm-dd hh:mm:ss 的格式放置
$comparedatestr="2006-08-12 00:00:00";
$comparedate=strtotime($comparedatestr);

//我在這裡運行函數以開始搜尋。
directory_tree($dir,$comparedate);

//這是執行搜尋的函數...
function directory_tree($address,$comparedate){

@$dir = opendir($address);

if(!$dir){ return 0; }
while($entry = readdir($dir)){
if(is_dir("$address/$entry") && ($entry != ".." && $entry != ".")){
directory_tree("$address/$entry",$comparedate);
}
else {

if($entry != ".." && $entry != ".") {

$fulldir=$address.'/'.$entry;
$last_modified = filemtime($fulldir);
$last_modified_str= date("Y-m-d h:i:s", $last_modified);

if($comparedate < $last_modified) {
echo $fulldir.'=>'.$last_modified_str;
echo "<BR>";
}

}

}

}

}
nieprzeklinaj at gmail dot com
11 年前
這裡有一個方便的小函數,可用於智慧快取覆蓋 :)
<?php
函數 img($src, $alt='', $attr='')
{
如果(
file_exists($src))
{
$lmod = filemtime($src);
echo
'<img src="'.$src.'?lmod='.$lmod.'" alt="'.$alt.'" '.$attr.' />';
}
}
?>
jay at fudge dot org
25 年前
如果您希望在父網頁上使用此功能,您應該使用 getlastmod()
例如:
<?php echo "上次修改時間:".date( "Y年m月d日 H:i:s.", getlastmod() ); ?>
在被包含的頁面中... 例如,作為所有頁面的通用頁尾包含檔案。
匿名
15 年前
請注意,下方許多人提供的用於取得目錄中特定時間後修改的檔案的函數,在 Windows 作業系統上*並不會*取得所有檔案。

如果您在資料夾內複製並貼上任何檔案,或從另一個資料夾複製檔案到此資料夾(例如可能會使用但不會立即修改的圖片),則這些複製檔案的修改時間不會更新,只有建立時間會更新。

您需要同時使用 filectime 和 filemtime 來確保取得已複製但未修改,但顯然是新的檔案。
Don
9 年前
要尋找目錄中最舊的檔案
$directory= "C:\\";

$smallest_time=INF;

$oldest_file='';

if ($handle = opendir($directory)) {

while (false !== ($file = readdir($handle))) {

$time=filemtime($directory.'/'.$file);

if (is_file($directory.'/'.$file)) {

if ($time < $smallest_time) {
$oldest_file = $file;
$smallest_time = $time;
}
}
}
closedir($handle);
}

echo $oldest_file;
csnyder at chxo dot com
18 年前
如果您的系統上 PHP 的整數類型只有 32 位元,則 filemtime() 處理超過 2GB 的檔案時會失敗,並顯示警告「stat 失敗」。所有與 stat() 相關的指令都會出現相同的行為。

作為解決方法,您可以呼叫系統的 stat 指令來取得檔案的修改時間

在 FreeBSD 上
$mtime = exec ('stat -f %m '. escapeshellarg ($path));

在 Linux 上
$mtime = exec ('stat -c %Y '. escapeshellarg ($path));

感謝「mpb dot mail at gmail dot com」針對 stat() 提供類似的評論。
info at daniel-marschall dot de
15 年前
判斷目錄中最新檔案的時間戳記可能很有用。(例如,如果您想找出專案上次修改的時間)。

以下函式將會幫助你

<?php

function getAllFiles($directory, $recursive = true) {
$result = array();
$handle = opendir($directory);
while (
$datei = readdir($handle))
{
if ((
$datei != '.') && ($datei != '..'))
{
$file = $directory . $datei;
if (
is_dir($file)) {
if (
$recursive) {
$result = array_merge($result, getAllFiles($file . '/'));
}
} else {
$result[] = $file;
}
}
}
closedir($handle);
return
$result;
}

function getHighestFileTimestamp($directory, $recursive = true) {
$allFiles = getAllFiles($directory, $recursive);
$highestKnown = 0;
foreach (
$allFiles as $val) {
$currentValue = filemtime($val);
if (
$currentValue > $highestKnown) $highestKnown = $currentValue;
}
return
$highestKnown;
}

// 使用範例

echo '最新的檔案擁有以下時間戳記:<br>';
echo date('Y-m-d H:i:s', getHighestFileTimestamp('../'));

?>
dma05 at web dot de
19 年前
關於 "notepad at codewalkers dot com" 的程式碼

這段程式碼寫得相當簡潔,但我只想指出,在 HTTP 請求中使用 "HEAD" 方法而非 "GET" 方法可能更好,因為這樣就不會下載整個資源...

http/1.1 定義片段
章節 "9.4 HEAD"

HEAD 方法與 GET 方法相同,但伺服器不得在回應中返回訊息主體。回應 HEAD 請求的 HTTP 標頭中繼資訊應與回應 GET 請求所傳送的資訊相同。此方法可用於獲取請求所暗示的實體中繼資訊,而無需傳輸實體主體本身。此方法通常用於測試超文字連結的有效性、可存取性和最近修改時間。[...]
-- 程式碼片段結束 ---

程式碼如下...

-- 程式碼片段 ---
fputs($handle,"HEAD $uri[path] HTTP/1.1\r\nHost: $uri[host]\r\n\r\n");
-- 程式碼片段結束 ---

此致,Magnus
contacto at hardcode dot com dot ar
15 年前
處理 SWF 檔案(Flash 動畫)時,有一個很好的方法可以避免瀏覽器快取。我以前都是手動操作,然後使用亂數,但當線上處理大型動畫時,這會變得乏味,因為即使沒有任何更改,伺服器也總是會下載整個動畫。
但是...

這樣做就可以了

base.swf?rand=<?php echo filemtime("base.swf") ?>

<embed src="base.swf?rand=<?php echo filemtime("base.swf") ?>" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="1680" height="1050">
tobias
11 年前
上述範例

$filename = 'somefile.txt';
if (file_exists($filename)) {
echo "$filename 最後修改時間:: " . date ("F d Y H:i:s.", filemtime($filename));
}

可以運作,但是從透過 PHP 提供靜態檔案的效能角度來看並不理想,因為它基本上需要執行兩個檔案系統操作(file_exists 和 filemtime)。更有效的方法是僅使用 filemtime 並使用以下方式節省 file_exists 的開銷

$filename = 'somefile.txt';
$fmtime = filemtime($filename);
if (!$fmtime) {
echo "$filename 最後修改時間:: " . date ("F d Y H:i:s.", $fmtime);
}
gerardj at home dot com
25 年前
如果您將上述程式碼放在您想要顯示日期戳記的每個頁面上,它就能正常運作。我發現,如果您在 include 或 require 的檔案中放置 filemtime(__FILE__) 之類的參考,則會返回被繼承檔案的修改時間,而不是執行繼承的檔案的時間。
Steve GS
4 年前
如果檔案不在執行指令碼的相同目錄中,除非您使用 $_SERVER,否則將會失敗。這是因為,就像 file_exists() 一樣,該命令在檔案系統上運作,而不是透過 HTTP。因此,這將無法正常運作(並且可能會顯示警告)

echo '<img src="' . $home_url . '/images/image.jpg?v=' . filemtime ($home_url . '/images/image.jpg') . '" />';

但這樣就可以了

echo '<img src="' . $home_url . '/images/image.jpg?v=' . filemtime ($_SERVER['DOCUMENT_ROOT'] . '/images/image.jpg') . '" />';

上面的第二個指令碼將確保任何更新的圖片都能保證取代其前身,而不會強制瀏覽器在每次訪問時都重新載入圖片。
arkadia81 at gmail dot com
11 年前
針對 tobias 的文章做一點修正

取代以下程式碼:
$filename = 'somefile.txt';
$fmtime = filemtime($filename);
if (!$fmtime) {
echo "$filename 最後修改時間:: " . date ("F d Y H:i:s.", $fmtime);
}

應該改成像這樣:
$filename = 'somefile.txt';
$fmtime = filemtime($filename);
if ($fmtime != false) {
echo "$filename 最後修改時間:: " . date ("F d Y H:i:s.", $fmtime);
}

filemtime() 函式失敗時會回傳 false,所以在第一個例子中永遠不會顯示修改日期。
james dot schafer at gotalk dot net dot au
14 年前
在 Windows 系統中,filectime() 會回傳建立時間。要取得修改時間,請使用 fileatime() 或 filemtime()。
Nilo
14 年前
簡易的快取程式碼寫法

<?php
$cache_file
= '快取檔案的 URI';
$cache_life = '120'; //快取時間,單位為秒

if (!file_exists($cache_file) or (time() - filemtime($cache_file) >= $cache_life)){
ob_start();
resource_consuming_function();
file_put_contents($cache_file,ob_get_flush());
}else{
readfile($cache_file);
}
?>
son9ne at gmail dot com
10 年前
如果您使用
<?php
$filename
= 'somefile.txt';
$fmtime = filemtime($filename);
if (!
$fmtime) {
echo
"$filename 最後修改時間:: " . date ("F d Y H:i:s.", $fmtime);
}
?>

請注意,如同文件中所述,這會產生警告。雖然 tobias 的觀點在正式環境中(錯誤回報關閉時)是正確的,這可以提升效能,避免使用 `file_exists`。然而,如果錯誤回報開啟且會寫入日誌... 情況就不是這樣了。顯然,這取決於伺服器規格和錯誤日誌的大小。在大多數情況下,使用 `file_exists` 方法仍然是理想的。
dagger80
14 年前
此外,在 32 位元系統上,filemtime() 也無法處理修改時間設定在 2038 年 1 月之後的檔案。這是 Unix 秒數的 time_t 溢位錯誤。

在 Windows 上,您可以將系統時間設定為任何未來的日期,任何您建立或編輯的新檔案都會自動更改為該未來日期。

如果因為某些原因不允許使用 exec,而且您可以透過網頁網址存取檔案(例如 https://127.0.0.1/yourfile.txt),另一個解決方法是從 HTTP 標頭取得 Last-Modified 時間(例如 get_headers(url)),並將其解析為 DateTime 物件。

我已經測試過,它適用於 2050 年和 3012 年等年份。
To Top