PHPスクリプトを作成しようとしています。スクリプトは終了していますが、設計されたプロセスを完了するのに10分ほどかかります。これは問題ではありませんが、プロセスを開始してから10分後に戻って、生成されたログファイルを表示するようにページを保持することはできますか?
さて、「 ignore_user_abort (true)」を使用できます
そのため、スクリプトは引き続き機能します(スクリプトの継続時間に注意してください。おそらく「 set_time_limit (0)」を追加してください)
ただし、ここでの警告:次の2行でスクリプトを停止することはできません。
ignore_user_abort(true);
set_time_limit(0);
サーバーに直接アクセスし、そこでプロセスを強制終了できる場合を除きます! (そこに来て、無限ループを繰り返し、何度も自分自身を呼び出して、サーバーを金切り声で止め、叫びました...)
キューとキューを処理するための外部スクリプトが必要なようです。
たとえば、PHPスクリプトはデータベーステーブルにエントリを入れてすぐに戻る必要があります。その後、毎分実行されるcronはキューをチェックし、各ジョブのプロセスをフォークします。
ここでの利点は、Apacheスレッドを10分間ロックしないことです。
この種のプロセスをWindowsで実行すると、多くの問題が発生しました。私の状況は、「スクリプト」の応答を気にしなかったという点で少し異なっていました。スクリプトを開始し、仕事で忙しいときに他のページリクエストが通過できるようにしたかったのです。
何らかの理由で;他のリクエストがハングするか、約60秒後にタイムアウトする問題がありました(Apacheとphpの両方が約20分後にタイムアウトするように設定されていました)。また、Firefoxは5分後に(デフォルトで)タイムアウトするため、Firefoxの設定を変更しないと、ブラウザーを介して何が起こっているのかわかりません。
私は、プロセスを開くプロセスとプロセスを閉じるメソッドを使用して、次のようにCLIモードでPHPを開きました:
pclose(popen("start php myscript.php", "r"));
これは、(startを使用して)phpプロセスを開き、開始プロセスを強制終了しますが、phpを必要な期間実行します-再びプロセスを強制終了して手動でシャットダウンする必要があります。タイムアウトを設定する必要はなく、それを呼び出した現在のページを継続させて、詳細を出力することができます。
これに関する唯一の問題は、スクリプトにデータを送信する必要がある場合、別のソース経由で送信するか、「コマンドライン」に沿ってパラメーターとして渡すことです。これはそれほど安全ではありません。
しかし、必要なものにうまく対応し、スクリプトが常に開始され、中断することなく実行できるようにしました。
これはまた助けになるかもしれません: PHPの非同期シェルexec
Shell_execコマンドはあなたが探しているものだと思います。
ただし、セーフモードでは無効になります。
PHPそれに関するマニュアル記事はこちらです: http://php.net/Shell_exec
それに関する記事がここにあります: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
使用できる別のオプションがあります。スクリプトCLIを実行します...バックグラウンドで実行され、必要に応じてcronjobとして実行することもできます。
例えば
> #!/usr/bin/php -q
<?php
//process logs
?>
これはcronjobとして設定でき、時間制限なしで実行されます。..この例はUNIXベースのオペレーティングシステム用です。
参考までに、私はPHPスクリプトを無限ループで実行しています。このループは処理を行い、過去3か月間ノンストップで実行されています。
ignore_user_abort()
を使用できます。ブラウザを閉じたり、別のページに移動しても、スクリプトは引き続き実行されます。
Bastiandoeenの答えに加えて、ignore_user_abort(true);
をcUrlリクエストと組み合わせることができます。
低いCURLOPT_TIMEOUT_MS
を設定してリクエスト中止を偽装し、接続が閉じられた後も処理を続けます。
function async_curl($background_process=''){
//-------------get curl contents----------------
$ch = curl_init($background_process);
curl_setopt_array($ch, array(
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER =>true,
CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms
CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute
CURLOPT_VERBOSE => 1,
CURLOPT_HEADER => 1
));
$out = curl_exec($ch);
//-------------parse curl contents----------------
//$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
//$header = substr($out, 0, $header_size);
//$body = substr($out, $header_size);
curl_close($ch);
return true;
}
async_curl('http://example.com/background_process_1.php');
[〜#〜] nb [〜#〜]
CURLが1秒未満でタイムアウトするようにしたい場合は、CURLOPT_TIMEOUT_MSを使用できますが、「Unixのようなシステム」にバグ/「機能」があります。 cURLエラー(28):タイムアウトに達しました。」この動作の説明は次のとおりです。
[...]
解決策は、CURLOPT_NOSIGNALを使用して信号を無効にすることです
長所
cons
リソース
ズク。
私はこれがうまくいくと確信しています:
<?php
pclose(popen('php /path/to/file/server.php &'));
echo "Server started. [OK]";
?>
「&」は重要です。シェルがプロセスの終了を待たないように指示します。
また、PHPでこのコードを使用できます(「bastiandoeen」が言ったように)
ignore_user_abort(true);
set_time_limit(0);
サーバー停止コマンドで:
<?php
$output;
exec('ps aux | grep -ie /path/to/file/server.php | awk \'{print $2}\' | xargs kill -9 ', $output);
echo "Server stopped. [OK]";
?>