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);
}

?>
Bunkai.Satori
  • 4,698
  • 13
  • 49
  • 77
  • 1
    First of all, check if your browser does even start those AJAX requests. – CBroe Oct 30 '13 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. – Bunkai.Satori Oct 30 '13 at 13:28
  • 1
    Did you _verify_ that the AJAX requests are starting via the network panel of your browser’s debug tools? – CBroe Oct 30 '13 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`. – Bunkai.Satori Oct 30 '13 at 13:45
  • 1
    As I said – check the network panel of the developer tools … – CBroe Oct 30 '13 at 13:47
  • @CBroe, great tool the Network pannel. I have never used it beforeo. I can say, after calling the main PHP script, the browser is in Pending state. JavaScripts do not get called in this case. Thank you, i wil mark all your answers by +1. – Bunkai.Satori Oct 30 '13 at 13:54

2 Answers2

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>
Cristian Bitoi
  • 1,557
  • 1
  • 10
  • 14
  • 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? – Bunkai.Satori Oct 30 '13 at 13:20
  • 1
    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 – Cristian Bitoi Oct 30 '13 at 13:23
  • 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 ` – Bunkai.Satori Oct 30 '13 at 13:25
  • 1
    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. – Cristian Bitoi Oct 30 '13 at 13:32
  • If I understand correctly, once the `fileDownload.php` is run, the browser stops its activity and waits for result from `fileDownload.php`. It means even JavasScript does not get executed until `fileDownload.php` finishes? – Bunkai.Satori Oct 30 '13 at 13:40
  • Yes. exactly, you make a request to the server, and wait for reponse – Cristian Bitoi Oct 30 '13 at 13:43
  • Ah great, so the advantage of AJAX is that during AJAX calls, the browser does not stop its activity. However, in my case, files can not be downloaded via AJAX calls, so the ` – Bunkai.Satori Oct 30 '13 at 13:50
  • 1
    Hmmm.. look for first answer of this question->(http://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax) and as a consequence have a look at this plugin.. look first for the demo to know if it is what you want -> (http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/) – Cristian Bitoi Oct 30 '13 at 13:55
  • Excellent example and great plug-in. Thank you very much, I have learned quite a lot from you. I am marking your answer as the Accepted Answer, and giving you +1 where possible. – Bunkai.Satori Oct 30 '13 at 14:08
  • let me get to you again. Are you sure, that placing the script into the `` into the webpage body, but apparently, the browser is still in waiting mode during the download script exectuion. – Bunkai.Satori Oct 30 '13 at 14:53
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.

Community
  • 1
  • 1
OlivierH
  • 3,875
  • 1
  • 19
  • 32
  • 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. – Bunkai.Satori Oct 30 '13 at 13:59
  • 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. – OlivierH Oct 30 '13 at 15:05
  • thanks for the addition. I decided to try `` 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 ` – Bunkai.Satori Oct 30 '13 at 15:41
  • 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. – OlivierH Oct 30 '13 at 15:50