Reputation: 338
There are 8000 html files in my data
directory.I parsed all the html files via traversing the target directory and to call the parse function.The filename will be displayed when to be parsed in my program.
<?php
base_dir="c:\data";
function parse($fname){
//to parse data from the file,omitted codes
echo $fname;
}
foreach(new RecursiveDirectoryIterator(base_dir) as $item){
parse($item);
}
?>
I found that the filenames will be displayed on the web page until my whole php file was executed,the filenames will be displayed in 10 minutes ,filename is not displayed one by one when one file is pared over.
How can i display the result instantly on the web page one by one,not wait until the whole php file was finished?
It is important for me to get the file name dispalyed that i know if there is problem in my code,if long time passed ,nothing displayed in the web page will make me nervous.
Upvotes: 0
Views: 920
Reputation: 57453
The simple way is to disable any output buffering, and use flush
for good measure. Also, disabling compression.
<?php
while (ob_get_level()) {
ob_end_clean(); // or ob_end_flush() if you want to display previous output from this script.
}
...
print "Whatever\n";
flush();
The above allows for minimal modification to your current code. It has few guarantees since the actual workflow between the parse process and your browser might contain entities (proxies, etc.) on which you have little or no control; if you execute external programs, those might be fully buffered instead of line buffered; and so on.
A more complicated (but satisfying) way is, if possible, break this into two chunks. This also poses a security risk that needs addressing.
In the main PHP file you output a Javascript variable (inside a Javascript block).
print "var filesToProcess = [\n";
print implode(",", array_map(
function($rawFileName) {
return '"' . /*javascriptQuote*/($rawFileName) . '"';
},
$filesToProcess
));
print "];\n";
This will make available to the client side Javascript an array with all the files.
You can now do the processing in AJAX:
function processOneFile() {
if (!window.filesToProcess.length) {
return;
}
// jQuery
$.post('/path/to/processor.php',
{ file: window.filesToProcess.pop() },
function(result) {
// ... see below
}
).always(function(){
window.setTimeout('processOneFile', 100);
});
}
window.setTimeout('processOneFile', 100);
This will call a PHP file with one file to process after the other. The result must be returned in JSON:
Header("Content-Type: application/json;charset=UTF-8");
die(json_encode(array( "status" => "OK", "file" => $file, "problem" => null )));
Security risk: the client is sending along a file name, any file name, and the script is executing something on that. In general you do not know who the client is, or who it may be, so you need to validate the file name (e.g. ascertain its basename does indeed exist in the target directory you sent in the first place):
if (!file_exists($yourDir . DIRECTORY_SEPARATOR . basename($file)) {
Header("Content-Type: application/json;charset=UTF-8");
die(json_encode(array(
"status" => "FAILED",
"file" => $file,
"problem" => "file could not be found",
/* "real-problem" => "Sorry, friend, it didn't work." */
)));
}
The array will be returned to the Javascript function above:
function(result) {
var msg;
if (result.status == "OK") {
msg = result.file + " OK";
} else {
msg = result.file + ": " + result.problem
}
$('#logDiv').append($('<p>').text(msg));
}
The above will transform a HTML entity
<div id="logDiv"></div>
in, say,
<div id="logDiv">
<p>file1.pdf OK</p>
<p>file2.pdf: missing UUID entry</p>
...
</div>
Since you know the initial filesToProcess.length, you can also display a progress bar (there are even jQuery plugins to do that as easy as $('#bar').progress(n*100/initialLength)
).
Or you can run lengthy processes by sending out two log lines, one just before the $.post
$('#logDiv').append($('<p>').text("Parsing " + file));
Upvotes: 0
Reputation: 362
If you need just to trace your program execution you could use error_log($fname) command instead of 'echo'. Less effort than AJAX and you could track execution 'live' by paste in Ubuntu terminal:
tail -F /var/log/apache2/error.log
(on other *nix path may be different).
Upvotes: 1
Reputation: 1
Do you mean showing results without refreshing webpage? IF that, you can use ajax to send request.
Upvotes: 0