SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

【php】rename関数にご用心

重箱の隅っこの話ですが、こんなことがありましたのメモ。


PHPの関数に、ファイルの最終更新日時を取得する「filemtime」という関数がある。

一連の処理中に一度でもfilemtimeすると、結果がキャッシュされる(マニュアルの注意に書いてあるとおり)。

ファイルの更新日時を参照してから、ファイルを書き換えて、また同じファイルの更新日時を参照すると、古い情報が返ってくる。


では、ファイルの更新日時を参照してから、ファイル名を削除して、また同じファイルの更新日時を参照すると?

→ unlink関数で削除した場合は、キャッシュはクリアしてもらえるそうなので問題なし(マニュアル)。


では、ファイルの更新日時を参照してから、ファイル名を変更して、また同じファイルの更新日時を参照すると?

→ rename関数でファイル名を変更したところ、

→ exec関数でコマンドの実行でファイル名を変更したところ、php4でも、php5でもキャッシュされている情報が返ってきた。


つまり?

まあ。。。キャッシュって大変ですね。


問題の確認用ソース

<?php
header('Content-Type: text/plain');

$log_file = '/tmp/filemtime.log';

// ログファイルにログを出力(無い場合は作られる)
error_log("test", 3, $log_file);
echo 'ファイルを書き換えました' . "\n";

// ログファイルの最終更新日時を出力
echo '現在の最終更新日時: ';
echo date('Y-m-d H:i:s', filemtime($log_file)) . "\n";

// ログファイルをリネーム(元の名前のファイルはなくなる)
rename($log_file, $log_file . '.bak');
//exec('mv ' . $log_file . ' ' . $log_file . '.bak');
echo 'ファイルをリネームしました' . "\n";

// 5秒お休み
sleep(5);
echo '5秒停止しました' . "\n";

// ログファイルにログを出力
error_log("test", 3, $log_file);
echo 'ファイルを書き換えました' . "\n";

// ログファイルの最終更新日時を出力
echo '現在の最終更新日時?: ';
echo date('Y-m-d H:i:s', filemtime($log_file)) . "\n";

//キャッシュをクリア
clearstatcache();
echo 'キャッシュしている結果をクリアしました' . "\n";

// ログファイルの最終更新日時を出力
echo '現在の最終更新日時!: ';
echo date('Y-m-d H:i:s', filemtime($log_file)) . "\n";

データベースを使うシステムばかりを扱っていると、ファイル操作をする機会がすっかりなくなってしまったりしますが、たまには思い出すとよいと思います。

関連するメモ

コメント