PHP - 使用 Ajax 刷新 While 循环数据 [英] PHP - Flushing While Loop Data with Ajax

查看:37
本文介绍了PHP - 使用 Ajax 刷新 While 循环数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我试了一下,但出于某种原因,除非我注释掉 echo str_repeat(' ',1024*64); 函数,当它被注释掉时,它会显示整个循环结果:

已处理 1 行.已处理 2 行.已处理 3 行.已处理 4 行.已处理 5 行.已处理 6 行.7 行已处理.已处理 8 行.已处理 9 行.已处理 10 行.

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

1 行已处理.已处理 2 行.已处理 3 行.已处理 4 行.已处理 5 行.已处理 6 行.已处理 7 行.已处理 8 行.已处理 9 行.已处理 10 行.

我也不确定如何终止 JavaScript 线程.所以总共有 2 个问题:

 1. 它一次返回整个 While 循环对象,而不是每次循环时.2. 我不确定如何终止 JQuery 线程.

有什么想法吗?以下是我目前的代码.

msgserv.php

asd.html

<头><script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" charset="utf-8"></script><style type="text/css" media="screen">.msg{ 背景:#aaa;填充:.2em;边框底部:1px #000 实心}.new{ 背景色:#3B9957;}.error{ 背景色:#992E36;}</风格><身体><中心><字段集><legend>计算文件中的行数</legend><input type="button" value="开始计数" id="startCounting"/><input type="button" value="停止计数!"onclick="clearInterval(not-Sure-How-To-Reference-Jquery-Thread);"/></fieldset></中心><div id="消息"><div class="msg old"></div>

<script type="text/javascript" charset="utf-8">函数添加味精(类型,味精){/* 添加div的简单助手.type 是 CSS 类的名称(旧/新/错误).msg 是 div 的内容 */$("#messages").append("<div class='msg "+ type +"'>"+ msg +"</div>");}函数 waitForMsg(){/* 这请求 url "msgsrv.php"当它完成(或错误)*/$.ajax({类型:获取",url: "msgsrv.php",async: true,/* 如果设置为非异步,浏览器将页面显示为正在加载.."*/缓存:假,timeout:2880000,/* 以毫秒为单位的超时设置为 8 小时 */成功:函数(数据){/* 当对 barge.php 的请求完成时调用 */addmsg("new", 数据);/* 添加对 .msg div 的响应(使用new"类)*/设置超时('waitForMsg()',/* 请求下一条消息 */1000/* ..1 秒后 */);},错误:函数(XMLHttpRequest,textStatus,errorThrown){addmsg("error", textStatus + " (" + errorThrown + ")");设置超时('waitForMsg()',/* 后重试.. */"15000");/* 毫秒 (15 秒) */},});};$('#startCounting').click(function() {等待消息();});

test.txt

12345678910

解决方案

使用:

应该在一个 php 线程中完成您需要的一切

编辑

看看 nickb 的回答,如果你正在寻找一种方法来简单地做到这一点,那就是遵循算法:

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

process.php中:

ignore_user_abort();//脚本将在后台完成尽管(...){echo "页面: $i
";ob_flush();}

EDIT 2 请求示例(有点不同和丑陋,但很简单).test_process.php:

//这个脚本会将 1 到 100 的数字写入文件(无论发生什么)//并不断向用户发送信息$fp = fopen('/tmp/output.txt', 'w') or die('打开失败');设置时间限制(120);忽略用户中止(真);for( $i = 0; $i <100; $i++){echo "<script type="text/javascript">parent.document.getElementById('foo').innerHTML += 'Line $i<br/>';</script>";回声 str_repeat('', 2048);冲洗();ob_flush();睡眠(1);fwrite( $fp, "$i
");}fclose($fp);

和主 html 页面:

<iframe id="loadarea"></iframe><br/><脚本>功能助手(){document.getElementById('loadarea').src = 'test_process.php';}函数杀死(){document.getElementById('loadarea').src = '';}<input type="button" onclick="helper()" value="Start"><input type="button" onclick="kill()" value="停止"><div id="foo"></div>

点击开始行后:

第 1 行2号线

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

如果你再次点击 Start 脚本开始从请求(重写文件)开始执行,那么并行请求也会这样做.

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

Using PHP, I would like to make a while loop that reads a large file and sends the current line number when requested. Using Ajax, I'd like to get the current line count and print it out onto a page. Using html buttons, I'd like to be able to click and activate or terminate a javascript thread that runs only ONCE and calls the ajax method.

I have given it a shot but for some reason, nothing prints unless I comment out the echo str_repeat(' ',1024*64); function and when it's commented out, it shows the entire loop result:

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.

In a single line instead of showing them in separate lines like:

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.

Also I'm not sure how to terminate the JavaScript thread. So 2 problems in total:

 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.

Any ideas? Below is my code so far.

msgserv.php

<?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

<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

1
2
3
4
5
6
7
8
9
10

解决方案

Using:

should do all you need in one php thread

EDIT

Take a look at nickb's answer, if you're looking for a way how to do this simply it would be following algorithm:

  1. javascript opens process.php via ajax (which will do all the work AND print status reports), you have to look up whether jQuery ajax supports continuous loading
  2. if user decides to stop refreshes you'll kill loading as show in provided link

In process.php:

ignore_user_abort(); // Script will finish in background
while(...){
  echo "Page: $i
";
  ob_flush();
}

EDIT 2 requested example (bit of different and ugly, but simple). test_process.php:

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

fclose( $fp);

And main html page:

<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>

After hitting start lines as:

Line 1
Line 2

Appeared in the div #foo. When I hit Stop, they stopped appearing but script finished in background and written all 100 numbers into file.

If you hit Start again script starts to execute from the begging (rewrite file) so would parallel request do.

For more info on http streaming see this link

这篇关于PHP - 使用 Ajax 刷新 While 循环数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆