возможен ли индикатор выполнения с php и javascript с использованием ajax - PullRequest
8 голосов
/ 22 апреля 2011

Мне было интересно, как сделать прогресс-бар, как в gmail.

Я пытался

<script src="jquery.js"></script>
<script>
$(function (){
    $.ajax({
        url: 'index.php',
        success: function(data) {
            $('#bar').html(data);
        }
    });
})
</script>
<div id="bar"></div>

А на index.php

[EDIT] : под sleep() я просто хотел имитировать непрерывный поток вывода, как многопоточные программы, которые не поддерживаются в php.

<?php

for($i=0; $i<=10; $i++)
{
    sleep(1);
    echo "$i";
}

кажется, что вывод выводится сразу, поэтому я сразу получаю результат 012345678910.

также я попробовал

setInterval(function (){
        $.ajax({
            url: 'index.php',
            success: function(data) {
                $('#bar').html(data);
            }
        });
    }, 1000);

Вместо этого у меня были проблемы с поддержанием значения 'progress', поэтому я сделал

<?php

session_start();

if(isset($_SESSION['value'])){
    if($_SESSION['value'] >= 10)
    {
        unset($_SESSION['value']);
    }
    else
    {
        $_SESSION['value']++;
    }
}
else
{
    $_SESSION['value'] = 0;
}

echo $_SESSION['value'];

как часть моего php. Но, похоже, я вызываю функцию AJAX на непрерывном интервале.

Мой вопрос,

  1. Как Google использует индикатор выполнения при входе в gmail. Получают ли они непрерывные 'stream' данных, как я пытался в моем первом примере, или отправляют (регулярно) запрос по какому-то URL (хотя и не через ajax ... через JSONP или что-то еще) и обновляют страницу как секунду?

  2. Могу ли я сделать то же самое с php, даже если не с php, могу ли я сделать это, используя javascript и другой серверный язык сценариев, где поддерживается многопоточность?

Ответы [ 5 ]

9 голосов
/ 22 апреля 2011

Я не уверен, что именно Gmail делает для индикатора выполнения, но вы можете добиться чего-то похожего в PHP, хотя это может быть немного сложно.

Сначала объясним, почему ваши примеры не работают:

Если вы эхом и спите, как в первом примере, это никогда не сработает. Ajax выполняет полный запрос, то есть если ответ не завершится, он будет ждать. Когда вы зацикливаетесь и спите, запрос не «закрывается» до тех пор, пока не завершится выполнение сценария PHP.

Если вы используете сеанс, как в другом примере, проблема становится хранилищем сеансов. Хранилище, как правило, блокируется во время выполнения скрипта, и оно не будет обновляться, чтобы учесть тот тип проверки прогресса, который вы хотите.

Что вы можете сделать, это записать прогресс в файл (или в базу данных) вручную. Например:

file_put_contents('progress.txt', 1);

Затем попросите другой скрипт прочитать файл и вывести его содержимое.

Это должно работать, потому что file_put_contents открывает, записывает и закрывает файл.

Использование какого-либо другого языка, кроме PHP, облегчит его. Многопоточность, возможно, облегчит, но не является обязательным требованием. Тем не менее, наличие непрерывно запущенного процесса сделает его проще (PHP запускает процесс только в течение вашего запроса и затем завершается)

3 голосов
/ 22 апреля 2011

Я думаю, что Gmail показывает прогресс, когда загружает все ресурсы, такие как файлы JS. Есть разные способы сделать это: вы можете динамически включить все ресурсы в JS или сделать так, чтобы все включенные файлы JS сообщали, что они были загружены.


Чтобы сделать вывод PHP частичным, используйте это:

ob.php

<?php

ob_start();

for ($i = 0; $i < 100; $i++) {
    echo "{$i}<br />";

    ob_flush();
    flush();

    usleep(100000);
}

.htaccess

php_value output_buffering "0"
3 голосов
/ 22 апреля 2011

запускайте код jquery с интервалом и используйте PHP, чтобы напечатать процент выполнения и затем нарисуйте полосу.

так что это будет что-то вроде

<script>
function bar()
{
 var v=getProgress(...);
 setTimeout("bar()",1000);
 drawBar();
}

function drawBar(l)
{
 //set div's length to l
}
</script>

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

<?php
/* get the request and calculate the job completion percentage and echo it !  */
?>
2 голосов
/ 13 ноября 2011

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

test.php:

<?php 
  for($i=0; $i<100; $i++)
  {   usleep(100000); //100ms
      echo 'A'; ob_flush(); flush();
  }
?>

test.html:

<body>
   <button onclick='call()'>call</button>
   <div id='progress'>...</div>
   <script>
      function fprogress(e) 
      { document.getElementById('progress').innerHTML ='progress: '+e.loaded +'%'; }
      function call()
      {  var req = new XMLHttpRequest();  
         req.addEventListener("progress", fprogress, false);
         req.open('GET', 'test.php', true);  req.send(null);
      }
   </script>
</body>

... так что test.php может быть любым JOB, который делает что-то ... и при этом ECHOes 100 символов (байтов) с мигающим буфером.

1 голос
/ 22 апреля 2011

По моему мнению, вы можете разделить процесс входа в систему на несколько частей и проверок.

Каждая выполненная проверка детали отправляет ответ на ваш индикатор выполнения, и ширина индикатора выполнения увеличивает эти шаблоны. После этого индикатор выполнения отправит следующий запрос вашему процессу входа в систему до шага, пока вы не получите 100% входа и перенаправления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...