[ PHP ] is_file 関数が正しい結果を返さない ( clearstatcache )

Pocket

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 関数以外にもキャッシュの影響を受ける関数は、以下の参考リンクより確認できます。

参考
スポンサーリンク

Pocket

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>