2

Scenario:

I have two PHP scripts to be called simultaneously:

  1. First script will run several minutes (PHP based file download), depending on downloaded file size
  2. Second PHP script is supposed to be called within regular intervals to monitor execution of the first script - file progress download. To avoid opening new windows upon script completion, it is called via AJAX.

Problem:

The regularly called AJAX monitoring script is not processed during the execution of the first long running PHP(later download) script. Only if the first script is finished the AJAX called PHP script gets processed.

I spent many hours over this problem. I have simplified my test scripts as much as possible. However, I still can not get the AJAX script working during execution of the main php script. Neither can I obtain intermediary feedback values from the main-download script, in any other way.

Would you be so kind and analyze my code samples please? They have the precise form as I use them now. If possible, would you be so kind and run them in your environment? I suspect the problem can be in my WAMP environment.

  • PHP Version 5.4.12
  • Apache/2.4.4 (Win64) PHP/5.4.12
  • Windows 7 x64
  • 8GB RAM

Code Samples:

JavaScript code calling both PHP scripts:

<!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 Monitoring Script(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 long-running script (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);
}

?>
6
  • 1
    First of all, check if your browser does even start those AJAX requests. Commented Oct 30, 2013 at 13:19
  • @CBroe, hi and thanks for the response. I am sure it starts. I did multiple experiments, probably too many. One experiment I've done was, that I let the AJAX calls run firstly, and couple of seconds later, i started the long-running php dowlnoad script. The AJAX scripts stopped working when the download php script started. Commented Oct 30, 2013 at 13:28
  • 1
    Did you verify that the AJAX requests are starting via the network panel of your browser’s debug tools? Commented Oct 30, 2013 at 13:32
  • To be honest, nope. I did not check it like that. I use Chrome to develop. Would you possibly give me short advice, please, how to check whether AJAX requests even started during execution of the fileDownload.php. Commented Oct 30, 2013 at 13:45
  • 1
    As I said – check the network panel of the developer tools … Commented Oct 30, 2013 at 13:47

2 Answers 2

3

The first script it's not send through ajax:

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

You simply redirect the user to another page, and because you have download headers in php, the file is downloaded in the same page.

You can easily achieve your scope through an iframe. You set the source of that iframe : 'PHP/fileDownload.php' and then simply call your ajax download checker.

Short example:

<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>
Sign up to request clarification or add additional context in comments.

10 Comments

Hi Christian, the main script (download script) is not meant to be called via AJAX. AJAX does not allow saving files. Only the monitoring should be sent through AJAX, which I believe is. However, if there is any other way to call the (download)PHP script so, that I can download the file, that would be really great. So you believe, the problem is that I call it in the above way?
View my edited answer.. through an iframe.. Yes, the problem is that in the actual format you make a request.. and for ajax verification to be call, the current request must complete
I see the example now. May I have two more questions please: Firstly, would you help me to understand the subject a bit more, why I can not call PHP scripts via AJAX during execution of the main script. Secondly, is there way, how to call the first main script via <iframe> from within JavaScript? I have to call both scripts upon one button press.
Http arhitecture is stateless, as a consequence the protocol use request-response arhitecture. You can not call your ajax function simply because your browser wait for response of fileDownload.php script. Because you call fileDownload.php in the main page, and not in an iframe, your javascript simple it's not call and ajax it's not executed.
Hmmm.. look for first answer of this question->(stackoverflow.com/questions/4545311/…) and as a consequence have a look at this plugin.. look first for the demo to know if it is what you want -> (johnculviner.com/…)
|
1

When you call

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

the script execution stops (not immediately, see https://stackoverflow.com/a/2536815/2806497).

Are you sure ajax calls to fileDownloadStatus.php are executed ?

A solution would be to call the fileDownloadStatus.php file by an ajax asynchronous call, or maybe to load it into an iframe you put in your page.

Hope that helps.

4 Comments

thanks for your tip. You said, the script execution stops not directly. I looked at the example, and I would say, that script execution did not stop at all in that case. What is the difference between direct and indirect stopping of script execution? Btw +1.
Oh sorry, grammar error. I should have used word "immediatly" instead of "directly". Edited. I mean that the execution stops after a few times, sometimes, with some browsers, a bit code is executed after the redirection. But it's not reliable, just bare in mind that scripts stops immediately.
thanks for the addition. I decided to try <iFrame> and placed my long-running php script <iframe src="PHP/fileDownload.php"></iframe> into body of my HTML code. However, it still stops the whole webpage and my browser waits on script completion. Would you have any idea, what can be wrong and why it still does not work? If I understand correctly, the script in <iframe> should be run asynchronously from the webpage processing and should not stop the browser during its execution.
Yes, using an iframe is just like opening a new tab in your browser : you got an independant document. Are you sure the whole webpage is stopped ? Monitor network with a tool like Firebug, and look : normally you will see your ajax calls. Your problem must be somewhere else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.