使用PHP ,我想做一个while循环,该循环读取一个大文件并在请求时发送当前行号。 使用Ajax ,我想获取当前行数并将其打印到页面上。 使用html按钮 ,我希望能够单击并激活或终止仅运行一次并调用 ajax方法 的javascript线程。
我给了它一个镜头,但是由于某种原因,除非我注释掉该echo str_repeat(' ',1024*64);函数,否则什么都不会打印,当注释掉它时,它将显示整个循环结果:
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.
另外,我不确定如何终止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.
有任何想法吗?下面是到目前为止的代码。
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
使用:
ignore_user_abort()
ob_flush()
应该在一个php线程中完成所有您需要的工作
编辑
看一下nickb的答案,如果您正在寻找一种简单地执行此操作的方法,它将遵循以下算法:
process.php
在process.php:
ignore_user_abort(); // Script will finish in background while(...){ echo "Page: $i\n"; ob_flush(); }
EDIT 2 要求的示例 (不同而难看,但简单) 。test_process.php:
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);
和主要的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>
在按如下开始线后:
Line 1 Line 2
出现在div中#foo。当我点击时Stop,它们停止出现,但脚本在后台结束,并将所有100个数字写入文件中。
#foo
Stop
如果Start再次点击,脚本将从乞讨(重写文件)开始执行,并行请求也会执行。
Start
有关http流的更多信息,请参见此链接