Подтвердить что ты не робот

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

Используя PHP, я хотел бы сделать цикл while, который читает большой файл и отправляет текущий номер строки по запросу. Используя Ajax, я хотел бы получить текущее количество строк и распечатать его на странице. Используя кнопки html, я хотел бы иметь возможность щелкнуть и активировать или закончить поток javascript, который запускается только один раз и вызывает метод 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 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
4b9b3361

Ответ 1

Использование:

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

ИЗМЕНИТЬ

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

  • javascript открывает process.php через ajax (который будет выполнять все отчеты о работе и печати), вам нужно выяснить, поддерживает ли jQuery 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

Появился в div #foo. Когда я нажал Stop, они перестали появляться, но script закончили в фоновом режиме и записали все 100 номеров в файл.

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

Подробнее о потоке http см. эта ссылка

Ответ 2

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

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

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

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

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

Ответ 3

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