Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progress bar AJAX and PHP

I want to create a progress bar for a server-side task ( written in php )

For learning purposes the example and task would be very simplistic. I would have a text field on the client page, read a number, pass it to the php script with ajax and make it calculate the sum of all numbers from 0 to number ( simplistic task that would take some time for big numbers, just to simulate some server-side work)

in the .html file I would create a timer that would call a function every n seconds getting the index that my for loop got to and update a progress bar.

My question is :
Is it possible to have in the same php file two functions , and how can I call a specific function with ajax : one that would block looping to number and another one I would call to get the current index the for-loop got to.

The code I have so far :

<!DOCTYPE html>
<html>
<head>
    <script>
        function myTimer()
        {
            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)
                    {
                        document.getElementById("percentageDiv").innerHTML=xmlhttp.response;
                        alert(xmlhttp.response);
                    }
              }
            xmlhttp.open("GET","getter.php",true);
            xmlhttp.send();
        }

        function loop(){
            var loop_index = document.getElementById("loop_nr").value;
            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)
                    {
                        document.getElementById("sumDiv").innerHTML="Total sum = " + xmlhttp.response;
                        clearInterval(myVar);
                    }
              }
            xmlhttp.open("GET","server_side.php?nr="+loop_index,true);
            xmlhttp.send();
            var myVar=setInterval(function(){myTimer()},1000);
        }
    </script>
</head>
<body>
<div id="percentageDiv"> Percentage div</div>
<div id="sumDiv"></div>
<input type="text" id="loop_nr">
<input type="submit" onclick="loop()">

</body>
</html>

server_side.php

<?php
    session_start();
    $index=$_GET["nr"];
    $progress = 0 ;
    $sum = 0 ;

    for ($i = 1; $i <= $index; $i++) {
        $sum = $sum + $i;
        $progress++;
        $_SESSION['progress'] = $progress;
    }
    echo $sum;
?>

getter.php

<?php
    session_start();
    $progress = $_SESSION['progress'];
    echo $progress;
?>

Thank You!

like image 294
Iulian Rosca Avatar asked Dec 08 '13 11:12

Iulian Rosca


1 Answers

Not only one question in here

Your question would be two:

  • How can I do AJAX calls to specific functions in PHP?
  • How can I do a progress bar with AJAX?

How can I do AJAX calls to specific functions in PHP?

Your AJAX code is fine. The only thing you have to do in your PHP is receive this call.

Look at your request. You send a variable nr with your request:

server_side.php?nr="+loop_index

That will help us in the php code to determine that this is an AJAX call to do the sum operation. Now in the PHP:

<?php session_start();

//We look at the GET php variable to see if the "nr" is coming
if(isset($_GET['nr'])) {
    //Its coming!. Now we procede to call our function to sum
    sum($_GET['nr']);
}

function sum($nr) {
    $progress = 0 ;
    $sum = 0 ;
    for ($i = 1; $i <= $nr; $i++) {
       $sum = $sum + $i;
       $progress++;
       $_SESSION['progress'] = $progress;
    }
    echo $sum;
}

Thats it.

How can I do a progress bar with AJAX?

We need to make other AJAX call to request the progress to PHP.
First, we do another AJAX call to retrieve the progress with a timer!

    var timer;
    
    //try to delete duplications. Do a generic function that does the request to php
    function makeRequest(toPHP, callback) {
        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)
                {
                    callback(xmlhttp.response);
                }
          }
        xmlhttp.open("GET",toPHP,true);
        xmlhttp.send();
     }

     function loop() {
         var loop_index = document.getElementById("loop_nr").value;
         makeRequest("server_side.php?nr="+loop_index, function(response) {
             document.getElementById("sumDiv").innerHTML="Total sum = " + response;
             clearInterval(timer);
         });
         timer=setInterval(makeRequest("getter.php", function(response) {
             document.getElementById("percentageDiv").innerHTML=response;
          }),1000);
     }

Then in the php side we retrieve this call as we did before and echo the $_SESSION['progress'] (as you already have)

<?php
    session_start();
    $progress = $_SESSION['progress'];
    echo $progress;
?>

And that's it!

Edit: Sessions must not be saved to a file (default PHP behaviour) because if you do that the "progress" AJAX will be blocked. You should store your sessions in a key-value database such as Redis to achieve parallelism and horizontal scalability.

like image 106
Tomás Avatar answered Oct 18 '22 08:10

Tomás