PHP文件修改时间(以毫秒为单位)

时间:2010-05-27 18:34:29

标签: php filemtime

我在那里,我正在编写一个单元测试,断言文件没有被修改。测试代码执行时间不到一秒,因此我想知道是否可以以毫秒为单位检索文件修改时间。 filemtime()函数以秒为单位返回UNIX时间戳。

我目前的解决方案是使用sleep(1)函数,这将确保在检查它是否被修改之前经过1秒。我不喜欢这个解决方案,因为它会大大减慢测试速度。

我无法通过get_file_contents()声明内容相等,因为可以重写的数据是相同的。

我猜这不可能,是吗?

5 个答案:

答案 0 :(得分:6)

function getTime($path){
    clearstatcache($path);
    $dateUnix = shell_exec('stat --format "%y" '.$path);
    $date = explode(".", $dateUnix);
    return filemtime($path).".".substr($date[1], 0, 8);
}

的getTime( “MYFILE”);

答案 1 :(得分:4)

尝试这个简单的命令:

ls --full-time 'filename'

你可以看到文件时间戳精度不是秒,它更精确。 (使用Linux,但不认为它在Unix中有所不同) 但是我仍然不知道用于获取精确时间戳的PHP函数,也许你可以解析系统调用的结果。

答案 2 :(得分:2)

AFAIK UNIX时间戳的精度是秒,因此这可能不太可能。

顺便说一句,请注意PHP在内部缓存filemtime()的返回值,因此之前应调用clearstatcache()

另一种方法可能是首先修改(或删除)文件的内容,以便您可以轻松识别更改。由于在执行每个测试后系统的状态应保持不变,因此无论如何在单元测试运行后恢复原始文件内容都是有意义的。

答案 3 :(得分:1)

如果文件系统是ext4(在Ubuntu等更新的unix / linux上很常见)或ntfs(Windows),那么mtime确实具有亚秒精度。

如果文件系统是ext3(或者其他人;这是前一段时间的标准并且仍由RHEL使用),则mtime仅存储到最近的秒。也许旧的默认值是PHP仅支持mtime到最近的第二个。

要在PHP中获取值,您需要调用外部util,因为PHP本身不支持它。

(我在仅具有英语语言环境的系统上测试了以下内容; stat的“人类可读”输出可能不同,或者strtotime行为在非英语语言环境中可能会有所不同。应该可以在任何时区正常工作,因为stat的输出包含strtotime尊重的时区说明符。)

class FileModTimeHelper
{
    /**
     * Returns the file mtime for the specified file, in the format returned by microtime()
     *
     * On file systems which do not support sub-second mtime precision (such as ext3), the value
     * will be rounded to the nearest second.
     *
     * There must be a posix standard "stat" on your path (e.g. on unix or Windows with Cygwin)
     *
     * @param $filename string the name of the file
     * @return string like microtime()
     */
    public static function getFileModMicrotime($filename)
    {
        $stat = `stat --format=%y $filename`;
        $patt = '/^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)\.(\d+) (.*)$/';
        if (!preg_match($patt, $stat, $matches)) {
            throw new \Exception("Unrecognised output from stat. Expecting something like '$patt', found: '$stat'");
        }
        $mtimeSeconds = strtotime("{$matches[1]} {$matches[3]}");
        $mtimeMillis = $matches[2];
        return "$mtimeSeconds.$mtimeMillis";
    }
}

答案 4 :(得分:0)

嗯。想象一下一个网络服务器,在这里我们结合使用PHP和例如nodeJS。在nodeJS中,当我们获取文件的修改时间时,它包含毫秒。在PHP中没有。现在让我们说,对于我们允许用户下载的任何大文件(许多千兆字节),我们拥有并维护对应的文件,其中包含整个文件的预先计算的MD5校验和。我们将此校验和存储在与原始文件同名的文件中,但同时还要加上文件的大小和修改时间。包括微妙的情况! (所有操作均由节点完成)

示例: GEBCO_2019.nc(11723617646字节) 和 GEBCO_2019.nc.11723617646-2019-10-31T15-03-06.687Z.md5

现在,在下载页面上,我们决定显示MD5校验和 这是使用PHP代码

哦,不!!

我们称它为filemtime,但遗憾的是我们无法获得毫秒数,因此我们无法计算出Md5文件的名称。

我们可以更改节点代码以忽略毫秒部分。

这就像PHP的不足导致我们选择的公分母比我们应有的低。

仅为了获取文件修改时间而不得不运行外部程序也异常可怕。如果您一次加载一次必须执行50或60次此操作,我希望它会使速度变慢一点!!!

现在,文件修改时间的准确性当然取决于系统。 PHP应该直接为我们提供一种获取时间的方法,如果不能的话,这是一个严重的缺陷。