1

ここに、いくつかのコントローラーにmyAction関数があります。そしてそれは1つのクラスインスタンスを持っています:

public function myAction() {

    ...
    $myAnalyzer = new Analysis();
    $myAnalyzer->analyze();
    ...
}

この関数analyze()に10分かかるとします。これは、my.phtmlを10分間ブロックすることを意味しますが、これは許容できません。私が欲しいのは、最初にmy.phtmlをレンダリングしてから、my.phtmlのanalyze()からの中間結果を表示することです。

function analyze() {

... 
    foreach($items as $rv) {

        ...
        ...
        // new result should be stored in db here 
    }

}

私の知る限り、PHPにはスレッドが1つしかないため、それは不可能です。そこで、my.phtmlからajax-callしてmyAnalyzerインスタンスを実行することにしました。

最初の質問:そうですか?ブロックせずにmyAction()で実行できますか?

OK、今私はjavascriptまたはJQueryの助けを借りてmy.phtmlからいくつかのスクリプト、たとえばworker.phpを使用してmyAnalyzerを実行します。

2番目の質問:各foreachループがいつ終了するかをどのように知ることができますか?言い換えると、worker.phpに何らかのシグナル(またはイベント)をmy.phtmlまたはzendフレームワークに送信させるにはどうすればよいですか?javascriptタイマーを使用してmy.phtmlを時間ベースで更新したくありません。中間データはDBに格納されることになっているので、私が知る必要があるのはそれだけです。

3番目の質問:ユーザーがページを離れると、myAnalyzerは停止します。そのために私はこのコードを持っています。

window.onbeforeunload = function(e) {

    // killer.php kills myAnalyzer
};

しかし、javascriptはmyAnalyzerとどのように通信できますか?process-idのようなものはありますか?つまり、worker.phpがmyAnalyzerを実行すると、そのプロセスIDがzendフレームワークに登録されます。そして、ユーザーがページを離れると、killer.phpはこのプロセスIDを使用してmyAnalyzerを停止します。

よろしくお願いします。

4

1 に答える 1

1

最初のQ.:ええ、それは正しいと思います。

2番目のQ.:ここでどういう意味かわかりません。以下のコード例を参照してください

foreach($data => $item) {
   ...
}
//code here will be executed only after foreach loop is done. 

3番目のQ.:このページを見てください。これをfalseに設定して(しかし、すでにそのようになっていると思います)、時々クライアントに何かを送信することができます。または、trueに設定して、ユーザーがまだconnection_aborted機能に接続しているかどうかを確認できます。ここで私が意味するのは、ajaxを使用してworker.phpを実行し、タイムアウトのためにブラウザーが切断しないように要求を構成できることです(したがって、ユーザーがページに留まっている間、接続は維持されます)。ただし、ユーザーがページを離れると閉じられます。

編集: 2番目の質問について。いくつかのオプションがあります:

1)共有メモリ(たとえば、memcachedなど)を使用できます。そして、時々別のajaxリクエストでサーバーを呼び出します。したがって、各ループが終了した後、memcachedに値を入力し、リクエスト中にその値を確認して、応答を作成し、その値に基づいてページを更新できます

2)部分応答のようなものがあります。XMLHTTPRequestを使用して応答を取得することは可能ですが、私が覚えているように、これは多くのブラウザーでサポートされていないため、現時点ではあまり役に立ちません。これについての詳細はありません。使用しようとしたことはありませんが、一部のブラウザーではXMLHTTPRequestを使用して応答の一部を処理できることは確かです。

3)XMLHTTPRequestの代わりにinvisibleiframeを使用してworker.phpを呼び出すことができます。この場合、parrentウィンドウで関数を呼び出すjavascriptを配置できる場所の一部を送信すると、その関数がページを更新します。これは、より多くの情報を取得したい場合の長期ポーリングCOMET実装の1つです。いくつかの落とし穴があります(たとえば、一部のブラウザで実行するには、応答として特定の量のシンボルを送信していることを確認する必要がある場合があります)が、それでも使用できます(一部のWebブラウザチャットはに基づいていますこれ)。

2)と3)は、3番目の質問の問題を自動的に解決するので良いです。同時に1)はもっと簡単かもしれませんが、3番目の質問の問題は解決しません。

もう1つ、スクリプトが長時間実行されるため、セッションが他のリクエストの実行をブロックする可能性があることを覚えておく必要があります(デフォルトのファイルベースのPHPセッションが使用されている場合-これは確実に発生します)

于 2012-09-03T05:10:15.950 に答える