19

基本的には、1 時間もかかるスクリプトを実行したいと思うかもしれません。

私が本当にやりたいことは、サードパーティの API を使用してユーザーに SMS を送信することです。つまり、基本的には、スクリプトに電話番号の配列を指定し、メソッドを起動して SMS を送信するようなものです。

ただし、1 つの SMS を送信するのに 5 秒かかると仮定すると、およそ 1 ~ 2 時間である 1000 の SMS を送信したいと考えています。set_time_limit()共有ホストにいるため使用できません。

これを行う 1 つの方法は、番号をセッションに保存し、各 SMS を実行し、javascript を使用してそのページを最後まで更新することです。このように、ブラウザを開いたままにしておく必要があり、インターネット接続が切断されると実行が停止します。

それで、これを行うより良い方法はありますか?

私が欲しいものを説明するのに十分明確であることを願っていますか?実行に数時間かかる可能性がある大きなスクリプトを、タイムアウトせずに実行したいと考えています。

4

7 に答える 7

21

コマンドラインまたはシェル スクリプト、cron ジョブなどから実行される PHP スクリプトにはタイムアウトがありません。

CLI で呼び出されるスクリプトの場合、関数を使用して PHP スクリプトのタイムアウトを動的に設定しset_time_limit()ても効果はありません。

于 2010-05-15T15:56:15.500 に答える
6

max_execution_timeコマンド ラインから実行される PHP スクリプトは、オプションの影響を受けません。
したがって、まったく心配する必要はありません。

于 2010-05-15T15:55:06.990 に答える
5

ホストが許可する場合は、cron ジョブが最適なソリューションです。cron ジョブは基本的に、特定の時間間隔で Web サーバーによって自動的に実行される通常の php スクリプトです。必要に応じて、5 分ごとに実行され、数値を 100 のバッチで処理するスクリプトを作成します (明らかに、時間間隔とバッチ サイズを調整して調整する必要があります)。これにより、サーバーの負荷が抑えられ、ホスティング プロバイダーがリソースを浪費するというトラブルが発生するのを防ぐことができます。

スクリプトが処理するバッチを追跡するために、track_batch テーブルをセットアップします。これらの列は、問題へのアプローチ方法を適切に示しているはずです。

id、date_run、start_record、end_record、final_run

基本的に:

  • 最後のバッチ実行の日付を確認してください。現在のバッチの現在の日付 (または使用する他の識別子) でない場合は、続行します。
  • 最後のバッチ実行現在の日付であった場合は、final_run 列をチェックして、すべての数値の処理が既に終了しているかどうかを確認します。
  • 処理する数値がまだある場合は、開始レコードと終了レコードを MySQL の LIMIT と組み合わせて使用​​して、スクリプトが次のバッチを取得するために使用する db クエリを作成します。
  • 数字を処理します。
  • このバッチからのすべての情報を track_batch テーブルに保存します。
  • クエリが返す数値の量が最大バッチ サイズを下回る場合は、最後に到達したので、final_run 列を 1 に設定できます。

スクリプトを取得したら、cron ジョブ自体をセットアップする必要があります。共有ホストは、これを行うための独自のカスタム インターフェースを持っている可能性が高いため、スクリプトが機能するようになったら、共有ホストに尋ねるのがおそらく最適です。

于 2010-05-15T16:10:35.747 に答える
3

を使用するのは最適なオプションではありません。これset_time_limit(0)は、バグがあり、スクリプトが無限ループに入った場合でも、無期限に実行されることを意味するためです。

代わりに、各 SMS に 5 秒かかると見積もる場合は、次のアプローチを使用します。

while( $there_are_more_sms_to_be_sent ){
  set_time_limit(30); // enough spare time, just in case.

  // Do your sending, blah blah
}

そうすれば、制限時間は30秒に順次更新されます。もちろん、その単一の で無限ループの問題が発生する可能性がありますが、その制限while内に他の呼び出しがある場合、その制限により、それらの呼び出しが非難されるのをwhile防ぐことができます。

于 2010-05-15T16:09:33.820 に答える
0

CRONジョブを実行できる場合

私は通常、キュー、マネージャー、およびワーカーを持っています。一度に 1 回 sms API を呼び出すことができない限り、このモデルが役に立ちます。また、各ワーカーが自分で管理するため、タイムアウトについて心配する必要はありません。

私は次のようなものを持っています:

<?php
// PSEUDO CODE
// grab pending from queue

// <for> {
// update to running
exec("/usr/bin/php /path/to/send.php {$id} > /dev/null &");
// }

send.php は各 SMS を送信します。cronジョブで設定できる最大頻度であるため、現在、これを300/分の速度で実行しています

于 2010-05-15T16:35:17.673 に答える
0

使えますか、使えませんset_time_limit()か?

できれば..それを使用してください:

<?php
// Runs forever and ever...
set_time_limit(-1);
?>
于 2010-05-15T15:55:17.530 に答える
0

JavaScript を使用する代わりに、Refreshメタ タグをページに追加することもできます。

<meta http-equiv="Refresh" content="2; url=http://yoururl/script.php&step=x" ?>

の 2 つはcontent="2; url=..、ページが読み込まれてから 2 秒後に URL を読み込むようにブラウザに指示します。

于 2010-05-15T16:30:56.330 に答える