Home > PHP > ignore_user_abort=falseなのにスクリプトが止まらない

ignore_user_abort=falseなのにスクリプトが止まらない

2月 20th, 2006

PHPでプログラムを書いているとたまに、数千~数万回のループを扱うことがあります。
そういったループを使ったスクリプトは、ブラウザ全体とはいかなくとも、開いているページが
ビジー状態に陥ります。ひどい時は真っ白になったりもします。
こういう時、ブラウザを閉じたり、中止ボタンを押すとブラウザ上ではビジー状態から
開放されるんですが、サーバー上ではどうなのか?

今までの経験では以下の2つのどちらかです。

1.止まらない。スクリプトの最後まで実行して、通常と同じように終了する。
2.即止まる。

微妙に違うならいいんですが、ここまで両極端だと困ります。
これについて調べて見たところ、PHPの設定に以下のような物があることがわかりました。

ignore_user_abort

ユーザーがブラウザを閉じたり中止ボタンを押した時にスクリプトを終了させるか
どうかを決定するフラグです。
オフィシャルでは「デフォルトでtrue」。つまりユーザーがブラウザを閉じても止まらない
設定になっている。とのことですが、うちで確認する限りデフォルトは「false」でした。

それはいいとして、このignore_user_abortがfalseに設定されている限り、
ユーザーがブラウザを閉じたり中止ボタンを押したらスクリプトは即終了するはずです。
しかし、僕が書いていたプログラムはブラウザを閉じようが中止ボタンを押そうが止まりませんでした。
これは何でだろうと思って、しばらくハマってしまいました。

この原因はよくよく見たら「ignore_user_abort」の紹介の部分に書いてあったんですが、
「ignore_user_abort=false」という設定の場合、ユーザーが接続を切断した後、
echoかprint等で何かを出力しようとして初めてスクリプトが終了するようです。
僕のスクリプトはループ中では何も出力しない状態だったために、ループを抜け出すまでは
止まらないスクリプトになってしまっていました。

ブラウザを閉じたり、中止ボタンを押した時、ブラウザからサーバーへ何か信号を送るようなことは
してないと思うので、即時に検出するのは無理なんだと思いますが、わかりにくい仕組み
だなと思います。この設定と同じ名前の「ignore_user_abort」関数の方ではこのことについては
触れてすらいないし。

対策としては、接続が切断されたら強制終了させたい場合は、ループ中で定期的に
何かを出力させる・・・でしょうか。
その後でHTTPヘッダを出力する必要がある場合は更にややこしいことになりそうです。

このエントリーをはてなブックマークに追加
はてなブックマーク - ignore_user_abort=falseなのにスクリプトが止まらない

PHP