41

PHPスクリプトを作成しようとしています。スクリプトは完成しましたが、設計されたプロセスを完了するのに10分ほどかかります。これは問題ではありませんが、ページをロードしたままにしておく必要があると思いますが、これは面倒です。プロセスを開始してから 10 分後に戻ってきて、生成されたログ ファイルを表示することはできますか?

4

10 に答える 10

50

「 ignore_user_abort (true)」を使用できます。

そのため、スクリプトは引き続き機能します (スクリプトの長さに注意してください。おそらく「set_time_limit (0)」を追加してください)。

ただし、ここで警告: 次の 2 行でスクリプトを停止することはできません。

ignore_user_abort(true); 
set_time_limit(0);

ただし、サーバーに直接アクセスしてプロセスを強制終了することはできません。(そこにいて、無限ループを実行し、何度も何度も自分自身を呼び出し、サーバーを金切り声で停止させ、怒鳴られました...)

于 2008-11-05T13:09:55.323 に答える
26

キューとキューを処理するための外部スクリプトが必要なようです。

たとえば、PHP スクリプトはエントリをデータベース テーブルに配置し、すぐに返す必要があります。次に、毎分実行される cron がキューをチェックし、各ジョブのプロセスを fork します。

ここでの利点は、Apache スレッドを 10 分間ロックしないことです。

于 2008-11-05T16:37:29.100 に答える
8

Windowsでのこの種のプロセスには多くの問題がありました。私の状況は、「スクリプト」の応答を気にしなかったという点で少し異なりました。スクリプトを開始して、作業中に他のページ要求が通過できるようにしたかったのです。

何らかの理由で; 他のリクエストがハングするか、約60秒後にタイムアウトするという問題がありました(Apacheとphpの両方が約20分後にタイムアウトするように設定されていました)。とにかく、Firefox は 5 分後に (デフォルトで) タイムアウトすることが判明したため、それ以降は、Firefox の設定を変更しない限り、ブラウザーで何が起こっているのかを知ることができません。

次のように、プロセス オープン メソッドとプロセス クローズ メソッドを使用して、cli モードで php を開きました。

pclose(popen("start php myscript.php", "r"));

これは ( start を使用して) php プロセスを開き、開始プロセスを強制終了して、必要な時間だけ php を実行したままにします。手動でシャットダウンするには、プロセスを強制終了する必要があります。タイムアウトを設定する必要はなく、それを呼び出した現在のページを続行して、詳細を出力することができました。

これに関する唯一の問題は、スクリプトにデータを送信する必要がある場合は、別のソースを介して送信するか、「コマンド ライン」に沿ってパラメーターとして渡すことです。これはあまり安全ではありません。

ただし、必要なものはうまく機能し、スクリプトが常に開始され、中断することなく実行できるようになりました。

于 2008-11-05T14:13:24.710 に答える
5

shell_exec コマンドが探しているものだと思います。

ただし、セーフモードでは無効になります。

それに関する PHP のマニュアル記事はこちら: http://php.net/shell_exec

ここにそれに関する記事があります: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

于 2008-11-05T13:08:37.400 に答える
4

使用できる別のオプションがあり、スクリプト CLI を実行します...これはバックグラウンドで実行され、必要に応じて cronjob として実行することもできます。

例えば

> #!/usr/bin/php -q

<?php

//process logs

?>

これは cronjob としてセットアップでき、時間制限なしで実行されます....ただし、この例は UNIX ベースのオペレーティング システム用です。

参考までに、いくつかの処理を行う無限ループで実行されているphpスクリプトがあり、過去3か月間ノンストップで実行されています。

于 2008-11-06T07:27:33.050 に答える
3

使用できますignore_user_abort()- そうすれば、ブラウザを閉じたり、別のページに移動したりしても、スクリプトは引き続き実行されます。

于 2008-11-05T13:09:49.100 に答える
2

ignore_user_abort(true);bastiandoeen の回答に加えて、cUrl requestと組み合わせることができます。

要求の中止を偽装して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');

注意

cURL を 1 秒未満でタイムアウトさせたい場合は、CURLOPT_TIMEOUT_MS を使用できますが、値が < 1000 ミリ秒でエラーが発生した場合に libcurl をすぐにタイムアウトさせるバグ/「機能」が「Unix ライクなシステム」にあります。 cURL エラー (28): タイムアウトに達しました". この動作の説明は次のとおりです。

[...]

解決策は、 CURLOPT_NOSIGNAL を使用してシグナルを無効にすることです

長所

  • メソッドを切り替える必要はありません (互換性のある Windows & Linux)
  • ヘッダーとバッファーを介した接続処理を実装する必要はありません (ブラウザーと PHP のバージョンに依存しません)。

短所

  • カールエクステンションが必要

資力

于 2015-02-21T13:11:38.030 に答える
1

ズク。

私はこれがうまくいくと確信しています:

<?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]";

?>
于 2014-01-11T13:46:47.963 に答える