AJAX和PHP的进度条

5
我想为服务器端任务(使用PHP编写)创建一个进度条。
为了学习目的,示例和任务非常简单。我将在客户端页面上有一个文本字段,读取一个数字,通过ajax将其传递给php脚本,并让它计算所有数字的总和,从0到数字(一个简单的任务,对于大数字需要一些时间,只是模拟一些服务器端工作)。
在.html文件中,我将创建一个定时器,每n秒调用一个函数,获取我的for循环的索引并更新进度条。
我的问题是:
在同一个php文件中是否可能有两个函数,以及如何使用ajax调用特定函数:一个函数将阻止循环到数字,另一个函数将调用以获取当前索引。
我目前拥有的代码:
<!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;
?>

感谢您!

你以前做过向 PHP 发送 AJAX 请求吗?这与之前的操作并没有什么不同,只是需要将进度值保存在 $_SESSION 中以便持久化。 - Tomás
我其实对于Ajax和PHP都是新手,我会把我目前有的代码发出来。 - Iulian Rosca
1
我正在思考这个问题。我的问题是如何使用ajax从php中调用特定的函数? - Iulian Rosca
我认为你拥有的PHP比AJAX更重要。也把它发布出来。 - Tomás
2个回答

13

这里不止一个问题

你有两个问题:

  • 如何在PHP中对特定函数进行AJAX调用?
  • 如何使用AJAX实现进度条?

如何在PHP中对特定函数进行AJAX调用?

你的AJAX代码很好。你需要在PHP中接收这个调用。

查看你的请求。你发送了一个带有变量nr的请求:

server_side.php?nr="+loop_index

这将帮助我们在PHP代码中确定这是一个执行求和操作的AJAX调用。现在在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;
}

就是这样。

如何使用AJAX创建进度条?

我们需要进行另一个AJAX调用来请求PHP中的进度。
首先,我们使用计时器进行另一个AJAX调用以检索进度!

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

然后在 PHP 端,我们像之前一样检索此调用,并输出 $_SESSION ['progress'](就像您已经执行的操作一样)。

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

就是这样啦!

编辑:会话不能保存到文件(PHP的默认行为),因为如果这样做,“进度” AJAX 将被阻塞。你应该将会话存储在键值数据库中,例如 Redis,以实现并行和水平扩展。


谢谢,到目前为止你帮了我很多。我已经编辑了问题中的代码。你能看一下并告诉我为什么我的progressDiv只有在sum-task完成后才会更新,之前都被阻塞了吗?(我在myTimer中得到了警报,任务完成后) - Iulian Rosca
2
问题已解决 - 我遇到了一个阻塞的问题,因为我没有关闭会话,导致ajax请求不是并行的。我将您的问题标记为答案,因为您帮了我很多!谢谢! - Iulian Rosca
我很高兴它对你有帮助! - Tomás
我很好奇样例代码是如何工作的。由于两个PHP脚本都需要会话才能工作,我不知道它们如何并行运行... - Goozak
@Goozak 会话不应保存到文件(默认PHP行为),因为这样做会阻塞“进度”AJAX。您应该将会话存储在键值数据库中,例如Redis,以实现并行性和水平可扩展性。 - Tomás

-7

这里是在PHP中制作进度条的解决方案,无需JavaScript仅在服务器端实现:

 echo "<div style=\"float:left;\">Start... </div>";
 for ($i = 0; $i<20; $i++){
    echo '<div style="float:left;background-color:red;height:20px;width:'.$i.'px"></div>';
    ob_flush();
    flush();
    usleep(100000);
 }
 echo "<div style=\"float:left\"> Done!</div>.";
 ob_end_flush();exit;

2
请不要抄袭代码,看到这样的代码真的很痛苦。 - Benjamin Eckstein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接