首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP -用Ajax循环数据刷新

PHP -用Ajax循环数据刷新
EN

Stack Overflow用户
提问于 2012-02-05 19:44:00
回答 4查看 26.7K关注 0票数 22

使用PHP,我想创建一个while循环,它读取一个大文件,并在请求时发送当前行号。使用Ajax,我希望获取当前行数并将其打印到页面上。使用html按钮,我希望能够单击并激活或终止只运行一次并调用ajax方法的javascript线程。

我尝试了一下,但由于某种原因,除非我注释掉了echo str_repeat(' ',1024*64);函数,否则什么都不打印,当它被注释掉时,它会显示整个循环结果:

1行(S)加工2行(S)加工3行(S)加工4行(S)加工5行(S)加工6行(S)加工7行(S)加工8行(S)加工9行(S)处理。

在一行中,而不是在单独的行中显示,例如:

代码语言:javascript
复制
1 row(s) processed.
2 row(s) processed.
3 row(s) processed.
4 row(s) processed.
5 row(s) processed.
6 row(s) processed.
7 row(s) processed.
8 row(s) processed.
9 row(s) processed.
10 row(s) processed.

另外,我也不知道如何终止JavaScript线程。因此,总共有两个问题:

代码语言:javascript
复制
 1. It's returning the entire While loop object at once instead of each time it loops.
 2. I'm not sure how to terminate the JQuery thread.

有什么想法吗?下面是我目前的代码。

msgserv.php

代码语言:javascript
复制
<?php

//Initiate Line Count
$lineCount = 0;

// Set current filename
$file = "test.txt";

// Open the file for reading
$handle = fopen($file, "r");

//Change Execution Time to 8 Hours
ini_set('max_execution_time', 28800);

// Loop through the file until you reach the last line
while (!feof($handle)) {

    // Read a line
    $line = fgets($handle);

    // Increment the counter
    $lineCount++;

    // Javascript for updating the progress bar and information
    echo $lineCount . " row(s) processed.";

    // This is for the buffer achieve the minimum size in order to flush data
    //echo str_repeat(' ',1024*64);

    // Send output to browser immediately
    flush();

    // Sleep one second so we can see the delay
    //usleep(100);
}

// Release the file for access
fclose($handle);

?>

asd.html

代码语言:javascript
复制
<html>
    <head>
        <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" charset="utf-8"></script>

        <style type="text/css" media="screen">
            .msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
            .new{ background-color:#3B9957;}
            .error{ background-color:#992E36;}
        </style>

    </head>
    <body>

    <center>
        <fieldset>
            <legend>Count lines in a file</legend>
            <input type="button" value="Start Counting" id="startCounting" />
            <input type="button" value="Stop Counting!" onclick="clearInterval(not-Sure-How-To-Reference-Jquery-Thread);" />
        </fieldset>
    </center>

    <div id="messages">
        <div class="msg old"></div>
    </div>

    <script type="text/javascript" charset="utf-8">
        function addmsg(type, msg){
            /* Simple helper to add a div.
        type is the name of a CSS class (old/new/error).
        msg is the contents of the div */
            $("#messages").append(
            "<div class='msg "+ type +"'>"+ msg +"</div>"
        );
        }

        function waitForMsg(){
            /* This requests the url "msgsrv.php"
        When it complete (or errors)*/
            $.ajax({
                type: "GET",
                url: "msgsrv.php",
                async: true, /* If set to non-async, browser shows page as "Loading.."*/
                cache: false,
                timeout:2880000, /* Timeout in ms set to 8 hours */

                success: function(data){ /* called when request to barge.php completes */
                    addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
                    setTimeout(
                    'waitForMsg()', /* Request next message */
                    1000 /* ..after 1 seconds */
                );
                },
                error: function(XMLHttpRequest, textStatus, errorThrown){
                    addmsg("error", textStatus + " (" + errorThrown + ")");
                    setTimeout(
                    'waitForMsg()', /* Try again after.. */
                    "15000"); /* milliseconds (15seconds) */
                },
            });
        };

        $('#startCounting').click(function() {
            waitForMsg();
        });
    </script>

</body>
</html>

test.txt

代码语言:javascript
复制
1
2
3
4
5
6
7
8
9
10
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-05 19:58:46

使用:

应该在一个php线程中完成您所需的所有工作。

编辑

看看nickb的答案,如果您想知道如何做到这一点,那么它将是如下算法:

  1. javascript通过ajax打开process.php (这将完成所有工作和打印状态报告),您必须查找jQuery ajax是否支持持续加载。
  2. 如果用户决定停止刷新,您将终止加载,如提供的链接所示

process.php

代码语言:javascript
复制
ignore_user_abort(); // Script will finish in background
while(...){
  echo "Page: $i\n";
  ob_flush();
}

编辑2请求的例子(有点不同和丑陋,但很简单)。test_process.php

代码语言:javascript
复制
// This script will write numbers from 1 to 100 into file (whatever happens)
// And sends continuously info to user
$fp = fopen( '/tmp/output.txt', 'w') or die('Failed to open');
set_time_limit( 120);
ignore_user_abort(true);

for( $i = 0; $i < 100; $i++){
    echo "<script type=\"text/javascript\">parent.document.getElementById( 'foo').innerHTML += 'Line $i<br />';</script>";
    echo str_repeat( ' ', 2048);
    flush();
    ob_flush();
    sleep(1);
    fwrite( $fp, "$i\n");
}

fclose( $fp);

和主页:

代码语言:javascript
复制
<iframe id="loadarea"></iframe><br />
<script>
function helper() {
    document.getElementById('loadarea').src = 'test_process.php';
}
function kill() {
    document.getElementById('loadarea').src = '';
}
</script>

<input type="button" onclick="helper()" value="Start">
<input type="button" onclick="kill()" value="Stop">
<div id="foo"></div>

击中起跑线后,如:

代码语言:javascript
复制
Line 1
Line 2

出现在div #foo中。当我点击Stop时,它们不再出现,但脚本在后台完成,并将所有100个数字写入文件。

如果再次按Start,脚本将从乞求(重写文件)开始执行,因此并行请求也会执行。

有关http流的更多信息,请参见此链接

票数 10
EN

Stack Overflow用户

发布于 2012-02-05 20:08:32

您对PHP和AJAX是如何交互的感到困惑。

当您通过AJAX请求PHP页面时,强制PHP脚本开始执行。尽管您可能使用flush()来清除任何内部PHP缓冲区,但在连接关闭之前,AJAX调用不会终止(即响应处理程序不会被调用),这是在读取整个文件时发生的。

要完成您想要的任务,我相信您需要这样的并行流程:

  1. 第一个AJAX帖子发送一个请求来开始读取该文件。此脚本生成一些unqiue,将其发回浏览器,生成一个实际执行文件读取的线程,然后终止。
  2. 所有后续AJAX请求都转到不同的PHP脚本,该脚本检查文件读取的状态。这个新的PHP脚本根据#1中生成的唯一ID发送文件读取的当前状态,然后退出。

您可以通过$_SESSION变量或将数据存储到数据库来完成进程间的通信。无论哪种方式,您都需要一个并行实现,而不是当前的顺序实现,否则您将继续同时获得整个状态。

票数 12
EN

Stack Overflow用户

发布于 2018-03-11 09:40:42

更简单的解决方案应该是使用本机(vanila ) XHR对象。

关于长轮询,有非常复杂的解决方案。

代码语言:javascript
复制
<?php
header('Content-Type: text/html; charset=UTF-8');
if (ob_get_level() == 0) ob_start();
for ($i = 0; $i<10; $i++){
  echo "<br> Line to show.";
  echo str_pad('',4096)."\n";
  ob_flush();
  flush();
  sleep(2);
}
echo "Done.";
ob_end_flush();

The JS:

代码语言:javascript
复制
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/some_service.php', true);

xhr.send(null);
xhr.onreadystatechange = function() {
  if (xhr.status == 200) {
    if (xhr.readyState == XMLHttpRequest.LOADING){
      console.log('response',xhr.response);
      // this can be also binary or your own content type 
      // (Blob and other stuff)
    }
    if (xhr.readyState == XMLHttpRequest.DONE){
      console.log('response',xhr.response);
    }
  }
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9152373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档