2016-08-11 6 views
0

は長い実行時間を持つPHPスクリプトはつまり、私は質問のいくつかの上に見えたブラウザ

に戻って更新を送信することを可能にし、どちらもが答えているようです私の質問、その一部は「私はどうやってこれをするのですか?」と思われます。残りの半分は「ちょっと、私が今やっているやり方 - これが最善の方法でしょうか?

私は、PHPスクリプトへの上にいくつかのデータを送信し、簡単なAjaxのスクリプトを持っている:

$.ajax({ 
    type: 'POST', 
    url: 'analysis.php',  
    data: { reportID:reportID, type:type, value:value, filter_type:filter_type, filter_value:filter_value, year:year },   
    success:function(dataReturn){   
     analysis_data = JSON.parse(dataReturn); 
     /* do stuff with analysis_data... */ 
}); 

それがデータベースをループし、いくつかの非常に複雑なクエリを実行すると、このPHPスクリプトは、実行するのに約3分かかります。

<?php 
session_start(); 
ob_start(); 
ini_set('max_execution_time', 180); 

$breaks = [ 1000, 2000, 4000, 6000, 8000, 10000, 20000, 50000, 99999999 ]; 
$breaks_length = count($breaks); 
$p = 0; 

foreach ($breaks as $b) { 

    $p++; 
    $percentage_complete = number_format($p/$breaks_length,2) . "%"; 

    $sql = "query that takes about 20 seconds to run each loop of $b...."; 

    $query = odbc_exec($conn, $sql); 
    while(odbc_fetch_row($query)){ 
    $count = odbc_result($query, 'count'); 
    } 

    $w[] = $count; 

    /* tried this... doesn't work as it screws up the AJAX handler success which expects JSON 
    echo $percentage_complete; 
    ob_end_flush(); 
    */ 
} 

echo json_encode($w); 
?> 

本の全作品 - しかし、彼らが働いて、それを見ることができるように、私が本当にしたいことは戻ってユーザに出力$percentage_completeに、各foreachループの後の道を見つけるされ、代わりにちょうどのためにそこに座ってのFontAwで2分彼らの目の前で回転する夢のアイコン。私はob_start();を使用してみました、だけでなく、ページが動作して行われるまで出力されません何もない、それはそれは台無しにさせ、私のAJAXの成功ハンドラに送り返されるものの一部である値を、エコー。 (私はJSON_encoded形式で出力する必要があります。

私が読んだスレッドでは、唯一の考えは前のページで$breaksの配列ループを開始することです同じページに6回ループし、Iループ一度、答えを返し、その後、$breaks配列の2番目の要素を使用して再度analysis.phpを呼び出すが、私は、これは物事を行くための最善の方法であるか分かりません。また

- このスクリプトを実行するためには、ユーザが待っていることを3分の間に、彼らはページ上の何かを行うことはできませんので、彼らはただ座って待たなければなりません。私は、このスクリプトを実行してユーザーのサーバーの残りの部分を「ロックダウン」しない方法があると確信していますが、私がGoogleで検索したすべてが私に良いこれは私が正確に何を検索するのか分かりません...

+0

あなたは右、($ percentage_complete)json_encodeをしましたか?あなたは "do_stuff"以外のJSコールバックに何も持っていませんか? –

+0

通常、コールバックはそれに戻って渡されるものは何でも解析し、あなたがフィードバックを表示することがしたかったページ上のいくつかの要素のinnerHTMLプロパティに代わる.... –

+0

疑問があること、実際のJSONレスポンスを処理する方法に関するものではありませんPHPページが成功の呼び出しに戻ってきています。これは、成功の呼び出しで実行するコードの長い部分です。うまくいきます。そして@Kkinsey、私はとして出力しようとした - 質問は、スクリプトは、彼らが「リアルタイム」で起こって進行状況を確認できるよう、ユーザーに何かを返すために、実行中の処理中に、私のためにどのような方法があるかどうかではありませんJSON - と私はそれが仕事を得ることができながら、スクリプトが完全に終了していたまで、それは何も出力しませんでした(私には無意味である...) –

答えて

1

あなたはSession Lockingとして知っているものに遭遇しています。PHPは基本的に、最初のリクエストが終了するまでsession_start()という別のリクエストを受け付けません。

私はあなたがそれを必要としないことを確認することができますので、あなたの問題への即時修正は完全にライン#1からsession_start();を削除することです。


今、画面上の割合を示すに関するご質問には:(変更)

analysis.php

<?php 
ob_start(); 
ini_set('max_execution_time', 180); 

$breaks = [ 1000, 2000, 4000, 6000, 8000, 10000, 20000, 50000, 99999999 ]; 
$breaks_length = count($breaks); 
$p = 0; 

foreach ($breaks as $b) { 

    $p++; 

    session_start(); 
    $_SESSION['percentage_complete'] = number_format($p/$breaks_length,2) . "%"; 
    session_write_close(); 

    $sql = "query that takes about 20 seconds to run each loop of $b...."; 

    $query = odbc_exec($conn, $sql); 
    while(odbc_fetch_row($query)){ 
    $count = odbc_result($query, 'count'); 
    } 

    $w[] = $count; 

    /* tried this... doesn't work as it screws up the AJAX handler success which expects JSON 
    echo $percentage_complete; 
    ob_end_flush(); 
    */ 
} 

echo json_encode($w); 

check_analysis_status.phpは、このファイルを使用してパーセンテージを取得します

<?php 
session_start(); 
echo (isset($_SESSION['percentage_complete']) ? $_SESSION['percentage_complete'] : '0%'); 
session_write_close(); 

あなたのAJAXはanalysis.phpへの呼び出しを行うたらそしてちょうどJSのこの作品を呼び出します。

// every half second call check_analysis_status.php and get the percentage 
var percentage_checker = setInterval(function(){ 
    $.ajax({ 
     url: 'check_analysis_status.php', 
     success:function(percentage){ 
      $('#percentage_div').html(percentage); 

      // Once we've hit 100% then we don't need this no more 
      if(percentage === '100%'){ 
       clearInterval(percentage_checker); 
      } 
     } 
    }); 
}, 500); 
+0

私は間違いなくここでセッション変数を使用していますが、前のページから簡単に呼び出すことができ、それらを私のajax POSTに渡すことができますセクション。この質問に答えるのに時間をとってくれてありがとう!ほんとうにありがとう!私がここにあるすべてのものを通して仕事をさせてください、読むべきことがたくさんあります。 –

1

私はこれをいくつかの方法で行いましたが、私が一番好きなパターンは3つのスクリプトを持つことです。この)、analysis_create.phpanalysis.php、およびanalysis_status.php。キーは、ステータスチェック(analysis_status.php)で参照するDBオブジェクトを作成することです。 analysis_create.phppercent_completeの列を有することになるDBテーブルにポスト内のすべてのデータを格納します。 analysis_create.php関数は、analysisのID /トークンを返す必要があります。フロントエンドがIDを取得すると、analysis.phpにポストしてから遅延(250ms)した後、要求が終了するのを待たずに要求を終了します。 analysis.phpは、DBからデータを読み込み、作業を開始する必要があります。 analysis.phpスクリプトでignore_user_abortが正しく設定されていることを確認する必要があります。 analysis.phpへのリクエストが終了すると、そのIDで長いポーリングをanalysis_status.phpに開始します。 analysis.phpはクエリを処理しているため、対応するDBレコードを完了率で更新する必要があります。 analysis_status.phpは、このレコードを検索して、完了したパーセンテージをフロントエンドに返す必要があります。

関連する問題