2

シナリオ:

同時に呼び出す 2 つの PHP スクリプトがあります。

  1. ダウンロードしたファイルのサイズに応じて、最初のスクリプトは数分間実行されます (PHP ベースのファイル ダウンロード)。
  2. 2 番目の PHP スクリプトは、最初のスクリプト (ファイルの進行状況のダウンロード) の実行を監視するために定期的に呼び出されることになっています。スクリプトの完了時に新しいウィンドウが開かないようにするために、AJAX 経由で呼び出されます。

問題:

定期的に呼び出される AJAX 監視スクリプトは、長時間実行される最初の PHP (後でダウンロード) スクリプトの実行中に処理されません。最初のスクリプトが終了した場合にのみ、PHP スクリプトと呼ばれる AJAX が処理されます。

私はこの問題に何時間も費やしました。テスト スクリプトを可能な限り単純化しました。ただし、メインのphpスクリプトの実行中にAJAXスクリプトを動作させることはできません。また、メイン ダウンロード スクリプトから他の方法で中間フィードバック値を取得することもできません。

私のコードサンプルを分析していただけませんか?今使っているそのままの形です。可能であれば、あなたの環境でそれらを実行していただけませんか? 私の WAMP 環境に問題があると思われます。

  • PHP バージョン 5.4.12
  • アパッチ/2.4.4 (Win64) PHP/5.4.12
  • ウィンドウズ 7 x64
  • 8GBのRAM

コード サンプル:

両方の PHP スクリプトを呼び出す JavaScript コード:

<!DOCTYPE html>
<html>
<head>
    <title>Title of the document</title>
</head>

<body onload="callScripts();">


<script type="text/javascript">

    // call both PHP scripts(download and monitoring) in desired order
    callScripts = function()
    {
        // run long running (later Download) PHP script
        console.log("Calling: PHP/fileDownload.php");
        window.location.href = 'PHP/fileDownload.php';

        // call the monitoring PHP script multiple times in 2 second intervals
        window.setTimeout(function(){startDownloadMonitoring()}, 1000);
        window.setTimeout(function(){startDownloadMonitoring()}, 3000);
        window.setTimeout(function(){startDownloadMonitoring()}, 5000);
        window.setTimeout(function(){startDownloadMonitoring()}, 7000);
        window.setTimeout(function(){startDownloadMonitoring()}, 9000);
    };


    // call monitoring PHP script via AJAX
    function startDownloadMonitoring()
    {
        console.log("Calling startDownloadMonitoring()...");

        var xmlhttp;

        if (window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.onreadystatechange = function()
        {
            if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {
                console.log("Response Received: " + xmlhttp.responseText);
            }
        }
        xmlhttp.open("GET", "PHP/fileDownloadStatus.php", true);
        xmlhttp.send();
    }
</script>
</body>
</html>

PHP監視スクリプト(fileDownloadStatus.php)

<?php

include 'ChromePhp.php';

// start session, update session variable, close session
session_start();
$_SESSION['DownloadProgress']++;
ChromePhp::log('$_SESSION[\'DownloadProgress\'] = ' . $_SESSION['DownloadProgress']);
session_write_close();    

echo "success";
?>

PHP 長時間実行スクリプト (fileDownload.php)

<?php
include 'ChromePhp.php';

// disable script expiry
set_time_limit(0);

// start session, define variable, close session
session_start();

// prepare session variables
$_SESSION['DownloadProgress'] = 10;

session_write_close();

// execute for 60 seconds    
for( $count = 0; $count < 60; $count++)
{
    sleep(1);
}

?>
4

2 に答える 2

3

ajax 経由で送信されない最初のスクリプト:

 // run long running (later Download) PHP script
  console.log("Calling: PHP/fileDownload.php");
  window.location.href = 'PHP/fileDownload.php';

ユーザーを別のページにリダイレクトするだけdownload headersで、php を使用しているため、ファイルは同じページにダウンロードされます。

を介してスコープを簡単に達成できますiframe。その iframe のソースを設定して'PHP/fileDownload.php'から、単に ajax ダウンロード チェッカーを呼び出します。

短い例:

<iframe src="PHP/fileDownload.php">

<script>
        window.setTimeout(function(){startDownloadMonitoring()}, 1000);
        window.setTimeout(function(){startDownloadMonitoring()}, 3000);
        window.setTimeout(function(){startDownloadMonitoring()}, 5000);
        window.setTimeout(function(){startDownloadMonitoring()}, 7000);
        window.setTimeout(function(){startDownloadMonitoring()}, 9000);
        // .... blah blah
</script>
于 2013-10-30T13:16:07.093 に答える
1

電話すると

    window.location.href = 'PHP/fileDownload.php';

スクリプトの実行が停止します (すぐではありません。 https://stackoverflow.com/a/2536815/2806497を参照してください)。

fileDownloadStatus.php への ajax 呼び出しが実行されていますか?

解決策は、ajax 非同期呼び出しで fileDownloadStatus.php ファイルを呼び出すか、ページに配置した iframe にロードすることです。

それが役立つことを願っています。

于 2013-10-30T13:23:06.267 に答える