PHP - Ajax로 데이터를 루프하는 동안 플러시
저는 PHP를 사용하여 큰 파일을 읽고 요청 시 현재 라인 번호를 전송하는 while 루프를 만들고 싶습니다.아약스를 이용해서 현재 라인 수를 받아서 페이지에 출력하고 싶습니다.저는 html 버튼을 사용하여 ONCE만 실행하고 agax 메서드를 호출하는 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.
또한 자바스크립트 스레드를 종료하는 방법을 잘 모르겠습니다.그래서 총 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.mss.messages
<?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);
?>
AS.D.S.D.D.
<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
당신은 PHP와 AJAX가 어떻게 상호작용하는지 혼란스럽습니다.
AJAX를 통해 PHP 페이지를 요청하면 PHP 스크립트 실행을 강제로 시작합니다.사용할 수도 있지만,flush()
모든 내부 PHP 버퍼를 지우기 위해 AJAX 호출은 전체 파일을 읽을 때 발생하는 연결이 닫힐 때까지 종료되지 않습니다(즉, 응답 핸들러가 호출되지 않음).
원하는 것을 달성하려면 다음과 같은 병렬 프로세스 흐름이 필요합니다.
- 첫 번째 AJAX 게시물은 파일 읽기를 시작하라는 요청을 보냅니다.이 스크립트는 일부 대기열 ID를 생성하여 브라우저로 다시 보내고 실제로 파일 읽기를 수행하는 스레드를 생성한 다음 종료합니다.
- 이후의 모든 AJAX 요청은 파일 읽기 상태를 확인하는 다른 PHP 스크립트로 이동합니다.이 새로운 PHP 스크립트는 #1에서 생성된 고유 ID를 기반으로 파일 읽기의 현재 상태를 전송한 후 종료됩니다.
다음을 통해 프로세스 간 통신을 수행할 수 있습니다.$_SESSION
데이터를 데이터베이스에 저장하는 방법을 사용할 수 있습니다.어느 쪽이든 현재 순차적인 구현 대신 병렬 구현이 필요합니다. 그렇지 않으면 전체 상태를 한 번에 계속 얻을 수 있습니다.
사용:
하나의 php 스레드에서 필요한 모든 것을 해야 합니다.
편집
nickb의 답변을 보십시오. 단순히 이를 수행하는 방법을 찾고 있다면 알고리즘을 따르는 것입니다.
- 는 Javascript를 엽니다.
process.php
작업을하는 Ajax를가 연속 하는지 여부를 . - 사용자가 새로 고침을 중지하기로 결정하면 제공된 링크에 표시된 대로 로드가 중지됩니다.
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
에 했습니다.#foo
가 내가 때칠을 때.Stop
그들은 나타나지 않았지만 스크립트는 백그라운드에서 끝냈고 100개의 모든 숫자를 파일로 썼습니다.
, 면치를 치면,Start
다시 스크립트는 구걸(실행 파일)에서 실행되기 시작하고 병렬 요청도 실행합니다.
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();
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);
}
}
}
Ajax를 하고 "Ajax" (Ajax 을를사파것다입니생요업됨트이령는용일을 하는 것입니다.setInterval
값을 가져오려면 진행률 표시줄을 업데이트합니다.
언급URL : https://stackoverflow.com/questions/9152373/php-flushing-while-loop-data-with-ajax
'prosource' 카테고리의 다른 글
MySQL Workbench에서 MariaDB Pph MyAdmin으로 데이터베이스 모델 내보내기 (0) | 2023.08.16 |
---|---|
봄 재시도 가능한 주석 클래스를 찾을 수 없음 예외 (0) | 2023.08.16 |
파일 이름별 킬 프로세스 (0) | 2023.08.16 |
Google 지도 스타일 스크롤 사용자? (0) | 2023.08.16 |
베어가 아닌 Git 저장소로 푸시하는 방법은 무엇입니까? (0) | 2023.08.11 |