PHP – Промывка данных Loop с помощью Ajax

Используя PHP , я хотел бы создать цикл while, который читает большой файл и отправляет текущий номер строки по запросу. Используя Ajax , я хотел бы получить текущее количество строк и распечатать его на странице. Используя кнопки html , я хотел бы иметь возможность щелкнуть и активировать или закончить поток javascript, который запускается только ONCE и вызывает метод ajax .

Я дал ему выстрел, но по какой-то причине ничего не печатает, если я не прокомментирую 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 

С помощью:

  • jQuery убить запрос ajax
  • ignore_user_abort()
  • ob_flush()

должен делать все, что вам нужно, в одной php-цепочке

РЕДАКТИРОВАТЬ

Взгляните на ответ nickb, если вы ищете способ, как это сделать, это будет следующий алгоритм:

  1. javascript открывает process.php через ajax (который будет выполнять все отчеты о работе и печати), вам нужно выяснить, поддерживает ли jQuery ajax непрерывную загрузку
  2. если пользователь решает прекратить обновления, вы будете убивать загрузку, как показано в предоставленной ссылке

В process.php :

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

EDIT 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); 

И главная страница 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 чисел в файл.

Если вы нажмете Start скрипт начнет запускаться из файла попрошайки (переписать файл), чтобы выполнить запрос на параллель.

Для получения дополнительной информации о потоке HTTP см. Эту ссылку

Вы смущены тем, как взаимодействуют PHP и AJAX.

Когда вы запрашиваете страницу PHP через AJAX, вы принудительно запускаете скрипт PHP. Хотя вы можете использовать flush() для очистки любых внутренних буферов PHP, вызов AJAX не будет завершен (т. Е. Обработчики ответа не будут вызываться), пока соединение не будет закрыто, что происходит, когда весь файл был прочитан.

Чтобы выполнить то, что вы ищете, я считаю, что вам нужен параллельный процесс, например:

  1. Первая почта AJAX отправляет запрос, чтобы начать чтение файла. Этот скрипт генерирует некоторый идентификатор unqiue, отправляет его обратно в браузер, порождает поток, который фактически выполняет чтение файла, а затем завершается.
  2. Все последующие запросы AJAX переходят на другой PHP-скрипт, который проверяет состояние чтения файла. Этот новый PHP-скрипт отправляет текущий статус чтения файла на основе уникального идентификатора, сгенерированного в # 1, а затем завершает работу.

Вы можете выполнить эту межпроцессную связь с помощью переменных $_SESSION или путем хранения данных в базе данных. В любом случае вам нужна параллельная реализация вместо текущей последовательности, иначе вы будете продолжать получать весь статус сразу.

Фокус в том, чтобы создать файл (обновленный через Ajax) и использовать setInterval чтобы получить его значение, а затем обновить индикатор прогресса.