PHP Doku:: Liefert Datum und Uhrzeit der letzten Dateiänderung - function.filemtime.html

Verlauf / Chronik / History: (50) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzDateisystemrelevante ErweiterungenDateisystemDateisystem-Funktionenfilemtime

Ein Service von Reinhard Neidl - Webprogrammierung.

Dateisystem-Funktionen

<<fileinode

fileowner>>

filemtime

(PHP 4, PHP 5)

filemtime Liefert Datum und Uhrzeit der letzten Dateiänderung

Beschreibung

int filemtime ( string $filename )

Gibt Datum und Uhrzeit zurück, wann die Datei das letzte mal modifiziert wurde, oder FALSE wenn ein Fehler auftrat. Das Datum wird als UNIX-Timestamp zurückgegeben, was für die Funktion date() sehr passend ist.

Das Ergebnis dieses Funktionsaufrufes wird zwischengespeichert. Siehe clearstatcache() für weitere Einzelheiten.

Diese Funktion ist nicht für remote Dateien geeignet, die zu prüfende Datei muss über das Dateisystem des Servers verfügbar sein.

Anmerkung: Diese Funktion gibt den Zeitpunkt zurück, an dem in die Datenblöcke einer Datei geschrieben wurde; d.h. den Zeitpunkt der Änderung des Inhalts der Datei.

Beispiel #1 filemtime() Beispiel

<?php
// Gibt z.B. aus:  somefile.txt was last modified: December 29 2002 22:16:23.

$filename 'somefile.txt';
if (
file_exists($filename)) {
    echo 
"$filename was last modified: " date ("F d Y H:i:s."filemtime($filename));
}
?>

Siehe auch filectime(), stat(), touch() und getlastmod().


32 BenutzerBeiträge:
- Beiträge aktualisieren...
myselfasunder at gmail dot XYZ dot com
31.10.2010 23:02
There's a deeply-seated problem with filemtime() under Windows due to the fact that it calls Windows' stat() function, which implements DST (according to this bug: http://bugs.php.net/bug.php?id=40568). The detection of DST on the time of the file is confused by whether the CURRENT time of the current system is currently under DST.

This is a fix for the mother of all annoying bugs:

<?php
function 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
erelsgl at gmail dot com
7.06.2010 10:08
Cheaper and dirtier way to code a cache:

<?php
$cache_file
= 'URI to cache file';
$cache_life = '120'; //caching time, in seconds

$filemtime = @filemtime($cache_file);  // returns FALSE if file does not exist
if (!$filemtime or (time() - $filemtime >= $cache_life)){
   
ob_start();
   
resource_consuming_function();
   
file_put_contents($cache_file,ob_get_flush());
}else{
   
readfile($cache_file);
}
?>
dagger80
7.04.2010 21:22
Also on 32-bit systems, filemtime() also does not work for files with modification time set beyond Jan 2038. It is the dreaded time_t overflow bug for unix seconds.

On windows you can set the system time to any arbitrary future date, and any new files you created or edited will automatically change to that future date.

If exec isn't permitted for some reason, and if you could access the file via an web url (e.g. http://localhost/yourfile.txt), another workaround is to get the Last-Modified time from the HTTP headers (e.g. get_headers(url) ), and parse it as a DateTime object.

I have tested it and it works for years like 2050 and 3012.
Tom
25.02.2010 11:45
I was looking at using filemtime() as part of a browser cache busting technique for css/js/image files and was considering whether caching the mtime using memcache would be beneficial to prevent multiple file system calls.

1000 filemtime() calls (including clearing the stat cache between calls) vs. 1000 memcache reads. filemtime() is significantly faster.

1000 filemtime() took: 0.004787
1000 memcache took: 0.075099
_michael
1.02.2010 20:09
While testing on Windows, I noticed that the precision of filemtime is just 1 second.

So if you use clearstatcache() and filemtime() to check if a file has been modified, it might fail to detect the change. The modifications just have to happen within less than a second.

(I ran into this with Apache on Windows XP.)
post at romcke dot no
31.01.2010 13:45
I spent some time wondering why I got the "stat failed", but it was simply due to the fact that I fed the function relative paths. Paths need to be absolute.

The simplest things...
Nilo
11.01.2010 8:01
Cheap and dirty way to code a cache:

<?php
$cache_file
= 'URI to cache file';
$cache_life = '120'; //caching time, in seconds

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);
}
?>
james dot schafer at gotalk dot net dot au
16.12.2009 10:36
On the Windows system filectime() returns the creation time. To find the changed time use fileatime() or filemtime().
contacto at hardcode dot com dot ar
31.08.2009 17:03
when working with swf files (flash animations), there is a nice way to avoid the browser cache. i used to do this by hand, then i used a random number, but with large animations while working online, it gets boring because the server always downloads the whole animation, even if there was no change.
but...

this will do the trick

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">
Anonymous
20.08.2009 0:52
Please note that many of the functions below that people have provided to get files modified after a certain time in a directory will NOT get all files on a Windows operating system.

If you copy and paste any file inside the folder or into the folder from another folder (such as images that may be used but aren't going to be modified right away), the modified time is not updated on these copied files, only the creation time.

You need to use filectime with filemtime to assure you get copied files that aren't modified but are obviously new.
info at daniel-marschall dot de
22.06.2009 12:59
It could be useful to determinate the timestamp of the newest file in a directory. (e.g. if you want to find out when the last change was made to your project).

Following function will help you:

<?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;
}

// Use example

echo 'The newest file has the time stamp:<br>';
echo
date('Y-m-d H:i:s', getHighestFileTimestamp('../'));

?>
javi at live dot com
2.02.2009 12:22
Filemtime seems to return the date of the EARLIEST modified file inside a folder, so this is a recursive function to return the date of the LAST (most recently) modified file inside a folder.

<?php

// Only take into account those files whose extensions you want to show.
$allowedExtensions = array(
 
'zip',
 
'rar',
 
'pdf',
 
'txt'
);

function
filemtime_r($path)
{
    global
$allowedExtensions;
   
    if (!
file_exists($path))
        return
0;
   
   
$extension = end(explode(".", $path));    
    if (
is_file($path) && in_array($extension, $allowedExtensions))
        return
filemtime($path);
   
$ret = 0;
   
     foreach (
glob($path."/*") as $fn)
     {
        if (
filemtime_r($fn) > $ret)
           
$ret = filemtime_r($fn);   
           
// This will return a timestamp, you will have to use date().
    
}
    return
$ret;   
}

?>
kbrobst at surveyresearchpartners dot com
30.03.2008 18:56
I created an application which stores files as blobs in a database, and retrieves them upon user request (into a webDAV-enabled area).  The files are touched so that they have the correct timestamp information after being retrieved.  After the user is done making any alterations, a script runs that checks for changes in the files (including timestamps).

It appears that working with timestamps on files under Windows systems (XP/Server 2003) is a problem, because the timestamp on files, for example, will toggle between 1pm and 2pm depending on the age of the file and if it is DST or not.

Try this experiment:

$timestamp_str = "2005.02.06 14:45:33";
$timestamp_pieces=split('[. :]',$timestamp_str);
$timestamp=mktime($timestamp_pieces[3], $timestamp_pieces[4], $timestamp_pieces[5], $timestamp_pieces[1], $timestamp_pieces[2], $timestamp_pieces[0]);
touch("c:\\timestamp_test.txt",$timestamp);

The file timestamp_test.txt shows up in the operating system as having a modification date of "Sunday, February 06, 2005, 2:45:33 PM" - which is the desired result.

But now look at the results of filemtime (only when in DST - it will report the correct timestamp during standard time):

$compare_timestamp=filemtime("c:\\timestamp_test.txt");
$compare_timestamp_str = date("Y.m.d H:i:s",$compare_timestamp);
echo "$timestamp ($timestamp_str) is the original timestamp.<br />\n";
echo "$compare_timestamp ($compare_timestamp_str) is the timestamp on the file.<br />\n";

The output looks like this:

1107726333 (2005.02.06 14:45:33) is the original timestamp.
1107722733 (2005.02.06 13:45:33) is the timestamp on the file.

The filemtime function reports a timestamp different from what the OS reports.  You'll likely need to code around this issue if you are attempting something similar - because this is not a PHP bug but a "Microsoft feature".
geeks at geekman dot info
18.02.2008 6:01
This is a very handy function for dealing with browser caching. For example, say you have a stylesheet and you want to make sure everyone has the most recent version. You could rename it every time you edit it, but that would be a pain in the ass. Instead, you can do this:

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

Sample output:

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

By appending a GET value (the UNIX timestamp) to the stylesheet URL, you make the browser think the stylesheet is dynamic, so it'll reload the stylesheet every time the modification date changes.
solarijj at gmail dot com
8.03.2007 21:02
To get the modification date of some remote file, you can use the fine function by notepad at codewalker dot com (with improvements by dma05 at web dot de and madsen at lillesvin dot net).

But you can achieve the same result more easily now with stream_get_meta_data (PHP>4.3.0).

However a problem may arise if some redirection occurs. In such a case, the server HTTP response contains no Last-Modified header, but there is a Location header indicating where to find the file. The function below takes care of any redirections, even multiple redirections, so that you reach the real file of which you want the last modification date.

hih,
JJS.

<?php

// get remote file last modification date (returns unix timestamp)
function GetRemoteLastModified( $uri )
{
   
// default
   
$unixtime = 0;
   
   
$fp = fopen( $uri, "r" );
    if( !
$fp ) {return;}
   
   
$MetaData = stream_get_meta_data( $fp );
       
    foreach(
$MetaData['wrapper_data'] as $response )
    {
       
// case: redirection
       
if( substr( strtolower($response), 0, 10 ) == 'location: ' )
        {
           
$newUri = substr( $response, 10 );
           
fclose( $fp );
            return
GetRemoteLastModified( $newUri );
        }
       
// case: last-modified
       
elseif( substr( strtolower($response), 0, 15 ) == 'last-modified: ' )
        {
           
$unixtime = strtotime( substr($response, 15) );
            break;
        }
    }
   
fclose( $fp );
    return
$unixtime;
}
?>
bastiaan nelissen
21.12.2006 15:20
"This function returns the time when the data blocks of a file were being written to, that is, the time when the content of the file was changed."

Well, the content of the file does not need to 'change'. Saving  file content without changes will be enough.

Understanding this helped me.
Benan Tumkaya (benantumkaya at yahoo)
14.08.2006 11:11
Here is a small but handy script that you can use to find which files in your server are modified after a  date/time that you specify. This script will go through all folders in the specified directory recursively and echo the modified files with the last modified date/time...

//Starts Here
//Put here the directory you want to search for. Put / if you want to search your entire domain
$dir='/';

//Put the date you want to compare with in the format of:  YYYY-mm-dd hh:mm:ss
$comparedatestr="2006-08-12 00:00:00";
$comparedate=strtotime($comparedatestr);

//I run the function here to start the search.
directory_tree($dir,$comparedate);

//This is the function which is doing the search...
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>";
                       }

                 }

            }

      }

}
csnyder at chxo dot com
11.08.2006 17:59
If PHP's integer type is only 32 bits on your system, filemtime() will fail on files over 2GB with the warning "stat failed". All stat()-related commands will exhibit the same behavior.

As a workaround, you can call the system's stat command to get the modification time of a file:

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

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

Thanks to "mpb dot mail at gmail dot com" for his/her similar comment on stat().
madsen at lillesvin dot net
26.09.2005 0:39
There are a couple of things to point out about the otherwise great example posted by "notepad at codewalkers dot com".

First of all, as "dma05 at web dot de" pointed out, use HEAD instead of GET - that's being nice to your fellow man.

Second, it will only allow communication on port 80. That can easilly be solved.

<?php
function remote_filemtime($url)
{
   
$uri = parse_url($url);
   
$uri['port'] = isset($uri['port']) ? $uri['port'] : 80;
   
$handle = @fsockopen($uri['host'], $uri['port']);
   
// ...
}
?>

But hey, thanks a lot for the function! I've really had great use of it.
dma05 at web dot de
23.04.2005 23:25
concerning "notepad at codewalkers dot com"'s code:

this code is pretty neat, but i just wanted to note that using the "HEAD"-method instead of the "GET"-method in the http-request might be preferrable, since then not the whole resource is being downloaded...

http/1.1 definiton snippet:
Section "9.4 HEAD"

 The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification. [...]
-- snippet end ---

the code would then be...:

-- snippet ---
fputs($handle,"HEAD $uri[path] HTTP/1.1\r\nHost: $uri[host]\r\n\r\n");
-- snippet end ---

regards, Magnus
notepad at codewalkers dot com
11.03.2005 10:53
i needed the ability to grab the mod time of an image on a remote site. the following is the solution with the help of Joe Ferris.

<?php

function 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');

?>
habazi at yahoo dot com
21.02.2005 19:13
"this is not (necessarily) correct, the modification time of a directory will be the time of the last file *creation* in a directory (and not in it's sub directories)."

This is not (necessarily) correct either. In *nix the timestamp can be independently set. For example the command "touch directory" updates the timestamp of a directory without file creation.

Also file removal will update the timestamp of a directory.

9.12.2004 17:30
A comment below states

  "When using this function to get the modified date of a directory,
   it returns the date of the file in that directory that was last modified."

this is not (necessarily) correct, the modification time of a directory will be the time of the last file *creation* in a directory (and not in it's sub directories).
aidan at php dot net
26.10.2004 2:42
If you're looking to convert timestamps to a duration, for example "10" to "10 seconds", or "61" to "1 minute 1 second", try the Duration class.

http://aidanlister.com/repos/v/Duration.php
adam at roomvoter dot com
1.05.2004 22:42
The snippet of code earlier that allows you to delete all files older than 2 weeks uses the function (filemtime) - which checks the original create date of the file (filesystem independent).  You MAY want to use filectime() - that looks at when the file was last changed on YOUR file system.

        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);
        }
wookie at at no-way dot org
14.09.2003 23:17
Another little handy tool; to get the most recent modified time from files in a directory. It even does recursive directories if you set the $doRecursive param to true. Based on a file/directory list function I saw somewhere on this site. ;)

function 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;
}
paranoid at dds dot nl
5.06.2003 14:43
To get the last modification time of a directory, you can use this:

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

Take note on the last dot which is needed to see the directory as a file and to actually get a last modification date of it.

This comes in handy when you want just one 'last updated' message on the frontpage of your website and still taking all files of your website into account.

Regards,
Frank Keijzers
thomas at NOSPAM dot gutschke dot com
7.04.2003 14:00
Here's a little code snippet if you need the last-modified-time for a remote file as filemtime() does not work on those. :)

<?php
$modified
= "";
function
read_header($ch, $header)
{
    global
$modified;
   
$length = strlen($header);
    if(
strstr($header, "Last-Modified:"))
    {
       
$modified = substr($header, 15);
    }
    return
$length;
}

function
last_mod($remote_file)
{
    global
$modified;
   
$ch = curl_init();
   
curl_setopt($ch, CURLOPT_URL, $remote_file);
   
curl_setopt($ch, CURLOPT_HEADER, 1);
   
curl_setopt($ch, CURLOPT_NOBODY, 1);
   
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');

   
$headers = curl_exec ($ch);
   
curl_close ($ch);
    return
$modified;
}
?>

use something like
    <?php echo strtotime(last_mod("http://www.php.net/")); ?>
to get the time as an Unix timestamp or
    <?php echo last_mod("http://www.php.net/"); ?>
to get the gmdate()-like time.
laurent dot pireyn at wanadoo dot be
27.09.2001 14:00
If you use filemtime with a symbolic link, you will get the modification time of the file actually linked to. To get informations about the link self, use lstat.

24.08.2001 4:08
When using this function to get the modified date of a directory, it returns the date of the file in that directory that was last modified.
jay at fudge dot org
29.06.1999 22:55
If you want this functionality for the parent web page you should use getlastmod()
i.e.
<?php echo "Last modified: ".date( "F d Y H:i:s.", getlastmod() ); ?>
within the included page... i.e. as a commont footer include for all pages
gerardj at home dot com
20.05.1999 5:27
The above code works fine if you place it on each page you want a date stamp on.  I've found that if you place a reference such as filemtime(__FILE__) in an included or required file, that the modification time of the inherited file will be returned, not the time of the file that did the ineriting.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)