PHPで簡易スリープタイマー・再。

PC版へ 2010年03月15日
ええと、だいぶ前に書いた奴、これ意図した動きをしてくれません。今更ながらですが、訂正。PHPはファイル情報に関するキャッシュを持っているのだなぁ。なので、

<?php
  $file = './text.txt' ;

  echo filemtime( $file ) . "¥n" ;
  touch( $file );
  echo filemtime( $file ) . "¥n" ;
?>
なんてスクリプトを実行しても、touch前のファイル更新時刻とtouch後のファイル更新時刻は同じタイムスタンプを返します。つまり、以下のプログラム(以前紹介したことのある関数)は意図した動作はしてくれません。

★これはまちがい★
<?php

function sleeptimer( $file , $sec , $timeout){
    $start = time();
    while(1){
        if( file_exists( $file )){
            if( time()-filemtime( $file) > $sec ){  //最低$sec秒あいだを空ける
                touch( $file );                            //ファイルの更新時刻を更新
                return true;                            //成功
            }else{
                if( time() - $start >= $timeout ){    //giveup
                    return false;
                }
                usleep( mt_rand(200000 , 800000 ) ); //0.2〜0.8秒待ちリトライ。
            }
        }else{
            touch( $file );
            return true;
        }
    }
}

?>

ファイル情報に関するキャッシュをクリアしてやれば思い通りの動作をします。

☆これなら意図した動作をします☆
<?php

function sleeptimer( $file , $sec , $timeout){
    $start = time();
    while(1){
        if( file_exists( $file )){
            clearstatcache();
            if( time()-filemtime( $file) > $sec ){  //最低$sec秒あいだを空ける
                touch( $file );                            //ファイルの更新時刻を更新
                return true;                            //成功
            }else{
                if( time() - $start >= $timeout ){    //giveup
                    return false;
                }
                usleep( mt_rand(200000 , 800000 ) ); //0.2〜0.8秒待ちリトライ。
            }
        }else{
            touch( $file );
            return true;
        }
    }
}

?>

clearstatcache()はファイル情報に関するキャッシュをクリアする関数です。

ということで、ご迷惑をおかけしました。

関連記事

<<前の記事 | HOME | 次の記事>>

コメント

匿名です

 疑問に思ったのですが、なぜファイルの更新日時なのでしょうか?

usleep()を使っているのであればそれ自身が遅延なのではと
思ったのですが、そしてもし確認がしたいのであれば、
開始前と開始後にmicrotime()を使えば良い気がします。


 すごく気になったので調べましたが、
PHPの公式リファレンスのmicrotime関数の使用例そのものが、
すごく良いタイマーとスリープの例が載っていました。

 板主さんの例だとどんな利点がありますか?