<?php
function dirmtime($path, $level=3)
{
$mtime = filemtime($path);
if (0 < $level--) {
foreach (glob($path."/*") as $file) {
if (is_dir($file)) {
$subtime = dirmtime($file, $level);
if ($mtime < $subtime) {
$mtime = $subtime;
// echo $level.' '.$file.' '.date(DATE_RFC822, $mtime)."<br>";
} } } }
return $mtime;
}
?>
ご教示いただきましてそれを使っております。この時間を各ディレクトリごとに収集してそのもっとも最近の値を計算し、それと現在時刻の差を表示させればいいと思います。どのようにすればよいでしょうか。
以下のような感じでしょうか。
関数dhhmmssは表示用に使っているだけです。
<?php function dhhmmss($t) { $d = (int)($t / (24 * 60 * 60)); $h = (int)(($t - $d * 24 * 60 * 60) / (60 * 60)); $m = (int)(($t - $d * 24 * 60 * 60 - $h * 60 * 60) / 60); $s = (int)(($t - $d * 24 * 60 * 60 - $h * 60 * 60) - $m * 60); return sprintf('%04d-%02d:%02d:%02d', $d, $h, $m, $s); } function difmtime($path, $level=3) { $now = time(); $mtime = filemtime($path); $dtime = $now - $mtime; if (0 < $level--) { foreach (glob($path . "/*") as $file) { if (is_dir($file)) { $subtime = dirmtime($file, $level); if ($dtime > $subtime) { $dtime = $subtime; // printf("(%02d) %s %s<br />\n", $level, dhhmmss($dtime), $file); } } } } return $dtime; } $dtime = fidmtime(最初のディレクトリ); echo '最新のものは ' . dhhmmss($dtime); ?>
Aディレクトリーの中にB,C,Dのサブディレクトリーがあった時、dirmtime()はA,B,C,Dの更新日時を取得していました。
それが問題だったかもしれません。それとglob()はGLOB_ONLYDIRオプションを付けるとディレクトリーだけ拾得できるようなので書き直してみました。
またglob()は名前の先頭がドットのものは拾わないようです。それが問題ならreaddir()を使うようにする必要があるでしょう
<?php function dirmtime($path, $myself = FALSE, $level=3) { $mtime = ($myself) ? filemtime($path) : 0; if (0 < $level--) { foreach (glob($path."/*", GLOB_ONLYDIR) as $dir) { $subtime = dirmtime($dir, TRUE, $level); if ($mtime < $subtime) { // echo $level.' '.$dir.' '.date(DATE_RFC822, $mtime)." >> ".date(DATE_RFC822, $subtime)."\n"; $mtime = $subtime; } } } return $mtime; }
dirmtime("A")のようにするとAディレクトリーの中にあるB,C,Dのサブディレクトリーだけの更新日時を調べます。
dirmtime("A", TRUE)のようにするとAディレクトリー、B,C,Dのサブディレクトリーの更新日時を調べます(Aも含む)。
<?php function globr($path, $myself = FALSE, $level=3) { $globr = ($myself) ? array($path) : array(); if (0 < $level--) foreach (glob($path."/*", GLOB_ONLYDIR) as $path) $globr = array_merge($globr, globr($path, TRUE, $level)); return $globr; }
各ディレクトリのパスを配列に入れて返します。
<?php function globmtime($glob) { $mtime = 0; foreach ($glob as $path) { $submtime = filemtime($path); if ($mtime < $submtime) { $mtime = $submtime; echo elapse(time()-$mtime).' '.date(DATE_RFC822, $mtime).' '.$path."\n"; //"<br>"; } } return $mtime; }
$globは各ディレクトリのパスが配列入ったとします。foreachで各ディレクトリのパスについてfilemtime($path)で更新日時を取得します。
最近の値とは一番大きい値ということなので現在の一番大きい値($mtime)より大きかったら入れ替えます。
echoは動作確認なので注釈か削除して下さい。
<?php function elapse($time) { $elp = array(); foreach (array('日'=>86400, '時'=>3600, '分'=>60, '秒'=>1) as $name=>$value) { if ($time > $value) { $u = intval($time / $value); $time -= $u*$value; $elp[] = $u.$name; } } return implode($elp,' '); } echo elapse(time()-globmtime(globr("対象ディレクトリ")));
elapse()は時刻の差を判りやすくするためだけのものです。
globr("対象ディレクトリ")で対象ディレクトリ内にあるサブディレクトリのパスを列挙した配列(対象ディレクトリは含まない)を入手し、globmtime()は各ディレクトリのパスから更新日時を調べて最新のものを返します。現在時刻はtime()で取得できますからこれとの差を取った値をelapse()で表示しています。
サブディレクトリの更新日時とそのサブディレクトリ内のファイルの更新日時とは必ずしも同期しません。
よってhttp://q.hatena.ne.jp/1270872723にあるような”最後にアップロードしてから31分です”というような目的には使えないと思います。
例えばディレクトリAにあるファイルを削除すればディレクトリAの更新日時は更新されます。それはもはや”最後にアップロード”された日時ではありません。
ファイルの更新日時を知るのであればhttp://q.hatena.ne.jp/1270519639にあるgetHighestFileTimestamp('対象ディレクトリ')を使うのが正しいでしょう。
ただパスの最後が/で終わってないとサブディレクトリは検索できないでしょう。
getHighestFileTimestamp('hoge')ではなくgetHighestFileTimestamp('hoge/')とする必要があります。
ありがとうございます。そうすると最終的にコードはどうなりますでしょうか。