9

私は現在、ファイルが変更されなかったことを主張する単体テストを書いています。テストコードの実行にかかる時間は1秒未満であるため、ファイルの変更時間をミリ秒単位で取得できるかどうかを知りたいと思います。filemtime()関数は、UNIXタイムスタンプを秒単位で返します。

私の現在の解決策は、sleep(1)関数を使用しています。これにより、変更されたかどうかを確認する前に1秒が経過したことが保証されます。テストの速度が大幅に低下するため、このソリューションは好きではありません。

書き換え可能なデータは同じであるため、get_file_contents()を介してコンテンツの同等性を表明することはできません。

不可能だと思いますよね?

4

5 に答える 5

10
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");

于 2013-11-27T16:52:47.957 に答える
4

この簡単なコマンドを試してください。

ls --full-time 'filename'

ファイルのタイムスタンプの精度は2番目ではなく、より正確であることがわかります。(Linuxを使用していますが、Unixでは違いはないと思います)しかし、正確なタイムスタンプを取得するためのPHP関数についてはまだわかりません。おそらく、システムコールの結果を解析できます。

于 2012-03-09T01:51:59.660 に答える
2

AFAIK UNIXタイムスタンプの精度は秒であるため、これは不可能な場合があります。

ところで、PHPはfilemtime()内部的にの戻り値をキャッシュするため、clearstatcache()前に呼び出す必要があることに注意してください。

別の方法として、最初にファイルの内容を変更(または削除)して、変更を簡単に識別できるようにすることもできます。各テストの実行後もシステムの状態は同じである必要があるため、単体テストの実行後に元のファイルの内容を復元することは、とにかく意味があります。

于 2010-05-28T09:39:27.683 に答える
2

ファイルシステムがext4(Ubuntuのような最近のUNIX / Linuxで一般的)またはntfs(Windows)の場合、mtime精度は1秒未満です。

ファイルシステムがext3(またはおそらく他のもの。これはしばらく前の標準であり、RHELによってまだ使用されている)場合、mtimeは最も近い秒単位でのみ保存されます。mtimeおそらく、その古いデフォルトが、PHPが最も近い秒までしかサポートしない理由です。

PHPで値をフェッチするには、PHP自体が値をサポートしていないため、外部utilを呼び出す必要があります。

(私は英語ロケールのみのシステムで以下をテストしました。の「人間が読める」出力は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";
    }
}
于 2013-09-30T17:44:44.537 に答える
0

うーん。PHPを組み合わせて使用​​するWebサーバーを想像してみてください。たとえば、nodeJSと言います。nodeJSランドでは、ファイルの変更時刻を取得すると、ミリ秒が含まれます。PHPではそうではありません。ここで、ユーザーがダウンロードできる大きなファイル(数ギガバイト)について、ファイル全体の事前計算されたMD5チェックサムを含む対応するファイルがあり、それを維持しているとしましょう。このチェックサムは、元のファイルと同じ名前のファイルに保存されますが、ファイルのサイズと変更時刻も付加されます。ミリ秒を含む!(すべてノードによって実行されます)

例:GEBCO_2019.nc(11723617646バイト)およびGEBCO_2019.nc.11723617646-2019-10-31T15-03-06.687Z.md5

ダウンロードページで、MD5チェックサムを表示することにしました。これはPHPコードを使用しています

大野!!!

filemtimeと呼びますが、残念ながらミリ秒を取得できないため、Md5ファイルの名前を特定できません。

ミリ秒の部分を無視するようにノードコードを変更することができます。

ここでのPHPの欠陥のように、必要以上に低い公分母を選択することになります。

また、ファイルの変更時間を取得するためだけに外部プログラムの実行に頼らなければならないことも非常に恐ろしいことです。1ページの読み込みでこれを50回または60回実行する必要がある場合は、処理速度が少し遅くなると思います。

現在、ファイルmod時間の精度は、もちろんシステムに依存しています。PHPは、この時間を取得する方法を直接提供する必要があります。それができない場合、それは深刻な欠陥です。

于 2019-11-22T09:47:41.567 に答える