クライアント接続を終了しても、処理を続行できます。すべて完了です。php / httpdグローバル設定で処理に時間がかかる場合は、phpタイムアウトを増やすこともできます。を参照してくださいset_time_limit();
。
これはあなたが尋ねたものとは正確には異なりますが、X / Y問題である可能性があると思うので、ここでは次の目的で使用できる手法を使用します。
- 処理開始ページをユーザーに表示します。
- ユーザー接続を閉じます。
- より長い処理を開始します。
つまり、基本的に、これは「Xの実行方法」ではなく、説明されているニーズに答えます。
発信者
// Ignore user abort and set Connection close header
ignore_user_abort(true);
header("Connection: close");
// Start controlled buffering
ob_start();
echo "<h1>Processing started, come back tomorrow to see results</h1>";
// Get buffer length and manually add it to headers.
$size = ob_get_length();
header("Content-Length: $size");
// Flush buffers, user sees "Processing started" message.
ob_end_flush();
flush();
// At this point connection to client should be closed already.
// Here we start our worker, there is no need to do fork() or
// anything like that. Client browser is not listening anymore.
// All we need to do is simply start working and start writing
// status logs to somewhere so that client can retrieve status
// with another request, let's say from checkworkerstatus.php
include "worker.php";
$worker = new worker();
$worker->start_long_processing();
一人で走り続けるcaller
ためにフォークしたり殺したりしませんか?worker
そうです、それは必要がないからです。
はい、「caller.phpは(Linux)システムでworker.phpを開始し、caller.phpはすぐに終了する必要があります(worker.phpがサーバー上で動作している間)」という動作を要求しました。ただし、マルチスレッドを実行したくない場合は、そのようにする必要はありません-phpを使用したシングルユーザーアプリ。ユーザーに1.何かを開始させ、2。実行したままにし、3。ユーザーを切断し、4。ユーザーがさらに何かを開始したり、すでに十分に退屈している場合は終了したりできる場所に戻ります。
もちろん、後ですべてflush();
を何かに置き換えることができます。違いは、クライアントがリッスンしないため、すべての出力が/ dev/nullという名前のブラックホールに送られることです。たとえば、次のようなものでテストします。
...end_flush();
flush();
// At this point connection to client should be closed already.
echo "Nobody sees this message";
while(rand(0,10) != 1) {
echo "Nobody sees this message";
error_log(date("mdyHis")." Still running...");
sleep(10);
}
...
詳細については、 http://php.net/features.connection-handlingを参照してください。バッファのフラッシュとユーザー接続の終了に問題があると思われる場合は、http://php.net/function.flush
もお読みください。PHPがマルチスレッドをサポートしない理由
についての別の質問(回答付き)もあります。