Thr*_*eaT 20 php ajax loops flush while-loop
使用PHP,我想创建一个while循环,它读取一个大文件并在请求时发送当前行号.使用Ajax,我想获取当前行数并将其打印到页面上.使用html按钮,我希望能够单击并激活或终止仅运行ONCE并调用ajax方法的javascript线程.
我已经给了它一个镜头,但由于某种原因,除非我注释掉该echo str_repeat(' ',1024*64);函数并且当它被注释掉时它没有打印,它显示了整个循环结果:
1行已处理.2行已处理.3行已处理.4行已处理.5行已处理.6行已处理.7行已处理.8已处理的行.9行已处理.10行已处理.
在一行中,而不是在单独的行中显示它们,如:
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.
Run Code Online (Sandbox Code Playgroud)
另外我不知道如何终止JavaScript线程.总共有2个问题:
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.
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?以下是我的代码.
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);
?>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
的test.txt
1
2
3
4
5
6
7
8
9
10
Run Code Online (Sandbox Code Playgroud)
nic*_*ckb 11
你对PHP和AJAX的交互方式感到困惑.
当您通过AJAX请求PHP页面时,您强制PHP脚本开始执行.虽然您可能正在使用flush()清除任何内部PHP缓冲区,但在关闭连接之前,AJAX调用不会终止(即,不会调用响应处理程序),这在读取整个文件时发生.
为了实现您的目标,我相信您需要一个这样的并行流程:
您可以通过$_SESSION变量或将数据存储到数据库中来完成此进程间通信.无论哪种方式,您都需要并行实现而不是当前的顺序实现,否则您将立即继续获得整个状态.
使用:
应该在一个PHP线程中做你需要的一切
编辑
看看nickb的答案,如果你正在寻找一种方法如何做到这一点,它只是遵循算法:
process.php通过ajax 打开(将完成所有工作和打印状态报告),你必须查看jQuery ajax是否支持连续加载在process.php:
ignore_user_abort(); // Script will finish in background
while(...){
echo "Page: $i\n";
ob_flush();
}
Run Code Online (Sandbox Code Playgroud)
编辑2请求的例子(一点点不同和丑陋,但很简单).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\n");
}
fclose( $fp);
Run Code Online (Sandbox Code Playgroud)
和主要的html页面:
<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>
Run Code Online (Sandbox Code Playgroud)
点击起跑线后:
Line 1
Line 2
Run Code Online (Sandbox Code Playgroud)
出现在div中#foo.当我点击时Stop,它们停止出现,但脚本在后台完成并将所有100个数字写入文件.
如果你Start再次点击脚本开始从begging(重写文件)执行,那么并行请求会执行.
有关http流的更多信息,请参阅此链接
更简单的解决方案应该是使用原生(vanila js)XHR对象。
有非常复杂的解决方案,关于长轮询
PHP:
<?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();
Run Code Online (Sandbox Code Playgroud)
JS:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22581 次 |
| 最近记录: |