PHP の is_file 関数などでファイルが存在しないにも関わらず true をリターン値として返す場合があります。このような場合は、キャッシュが影響している可能性が高いです。
スポンサーリンク
ファイルの存在確認を行うサンプルコード
以下のサンプルコードは期待する動作となることが確認できます。ファイルの存在確認には is_file 関数を使用しています。
// 存在するファイルパスを指定する $path = 'path/to/exist/file'; // ファイルの存在確認 var_dump(is_file($path)); // true // ファイルの削除 unlink($path); // ファイルの存在確認 var_dump(is_file($path)); // false
is_file 関数が期待しない動作となる検証コード
次に以下のように、ファイルの存在確認を2度行う検証コードを実行してみます。ただし、一度目と二度目の確認の間に PHP とは関係のないエクスプローラや、シェルでファイルを削除しています。
すると、2度目の確認では is_file 関数が true を返します。
// 存在するファイルパスを指定する $path = 'path/to/exist/file'; // ファイルの存在確認 var_dump(is_file($path)); // true /* * 一定時間待機 * この間にエクスプローラーやシェルから対象のファイルを削除する */ sleep(20); // ファイルの存在確認 var_dump(is_file($path)); // true
この動作は PHP がパフォーマンス向上のためにいくつかのファイルシステム関数の戻り値をキャッシュしているためです。1度目のスクリプトが正しい値を返したのは、unlink 関数の呼び出しによって内部的にキャッシュがクリアされていたからです。
これらキャッシュ機能による誤動作を防止するには、次のように clearstatcache 関数でキャッシュをクリアする必要があります。
// 存在するファイルパスを指定する $path = 'path/to/exist/file'; // ファイルの存在確認 var_dump(is_file($path)); // true /* * この間にエクスプローラーやシェルから対象のファイルを削除する。 */ sleep(20); // ファイルステータスキャッシュのクリア clearstatcache(); // ファイルの存在確認 var_dump(is_file($path)); // false
なお、is_file 関数以外にもキャッシュの影響を受ける関数は、以下の参考リンクより確認できます。