簡體   English   中英

PHP文件修改時間(以毫秒為單位)

[英]PHP file modification time in milliseconds

在那兒,我當前正在編寫一個單元測試,該測試斷言一個文件沒有被修改。 測試代碼的執行時間不到一秒,因此我想知道是否有可能以毫秒為單位檢索文件修改時間。 filemtime()函數以秒為單位返回UNIX時間戳。

我當前的解決方案是使用sleep(1)函數,該函數將確保在檢查是否已修改之前經過了1秒鍾。 我不喜歡這種解決方案,因為它會使測試速度大大降低。

我無法通過get_file_contents()聲明內容相等,因為可以重寫的數據是相同的。

我猜這是不可能的,是嗎?

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”);

試試這個簡單的命令:

ls --full-time 'filename'

並且您可以看到文件時間戳精度不是第二,而是更精確。 (使用Linux,但不要認為它與Unix有所不同),但我仍然不了解用於獲取精確時間戳的PHP函數,也許您可​​以解析系統調用的結果。

AFAIK UNIX時間戳記的精確度是秒,因此這不可能。

順便說一句,請注意,PHP在內部緩存了filemtime()的返回值,因此應在之前調用clearstatcache()

另一種方法是首先修改(或刪除)文件的內容,以便您輕松識別更改。 由於每次執行測試后系統的狀態都應保持不變,因此在單元測試運行后恢復原始文件內容還是有意義的。

如果文件系統是ext4 (在較新的Unix / Linux如Ubuntu上很常見)或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";
    }
}

想象一下一個網絡服務器,在這里我們結合使用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應該直接為我們提供一種獲取時間的方法,如果不能的話,這是一個嚴重的缺陷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM