Как вы запускаете длинный PHP-скрипт и продолжаете отправлять обновления в браузер по HTTP? - PullRequest
6 голосов
/ 08 июня 2010

Как вы запускаете длинный PHP-скрипт и продолжаете отправлять обновления в браузер по HTTP?

Как-то связано с буферизацией вывода, но я точно не знаю, как.

Ответы [ 5 ]

3 голосов
/ 08 июня 2010

Буферизация вывода работает в правильном направлении, вы начинаете буферизацию вывода с ob_start(), как если бы вы работали с сеансами (session_start) где-то в верхней части вашего скрипта, перед отправкой любого вывода.

Затем вы можете использовать ob_flush и flush, чтобы продолжать сбрасывать вывод. Например, если вы находитесь в цикле foreach и в конце каждого цикла вы хотите вывести новую строку и подождать 1 секунду, вы можете сделать это.

Но также посмотрите на set_time_limit, потому что в противном случае люди могут испытать тайм-аут после 30 секунд или около того.

Еще одно быстрое замечание: некоторые браузеры требуют минимального количества байтов вывода, прежде чем они начнут его показывать. Я не уверен, сколько это было байтов, я думаю, что это было около 4000. Кроме того, некоторые браузеры не будут отображать определенные элементы (например, таблицы), пока они не будут закрыты. Так что промывка там тоже не сработает.

2 голосов
/ 08 июня 2010

Это похоже на то, что вы ищете:

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

Буферизация вывода

Функция ob_start () используется для создать новый выходной буфер, и вы может сразу же начать писать по распечатывать содержимое как обычно. однажды у вас есть открытый буфер, есть два способы закрыть его: ob_end_flush () и ob_end_clean (), оба из которых заканчивают буфер, но сделать это в слегка различные пути. Бывший заканчивает буфера и отправляет все данные на выход, и последний заканчивает буфер без отправив его на выход, эффективно уничтожить любую информацию, которую вы сохранили там. Каждый кусок текста выводится, пока выходной буфер open помещается в этот буфер как в отличие от отправки на выход. Рассмотрим следующий скрипт:

<?php
  ob_start();
  print "In first buffer!\n";
  ob_end_flush();
  ob_start();
  print "In second buffer!\n";
  ob_end_clean();
  ob_start();
  print "In third buffer!\n";
?>

Этот скрипт выведет "В первую очередь буфер ", потому что первый текст помещается в буфер, затем сбрасывается ob_end_flush (). "Во втором буфере" не будет распечатан, потому что он помещается в буфер, который очищается с помощью ob_end_clean (), а не отправлено на выход. Наконец, скрипт распечатает "в третий буфер" потому что PHP автоматически открывается выходные буферы, когда он достигает конца сценария.

1 голос
/ 08 июня 2010

Я получил обновление страницы, используя простой вывод HTTP, чтобы заставить его работать:

  • Убедитесь, что вы закрыли все открытые элементы в <body>, иначе он не будет отображаться
  • Заключить выводимый текст в элемент (например, <p>)
  • Использовать буферизацию вывода и нормальную очистку
  • Проверено на Firefox 3

Вот мой код:

for ($nc=0; $nc<10; $nc++){

    // delay just to test
    sleep(1);

    // send message to browser
    ob_end_clean();
    ob_start();
    echo "<p>Update ".$nc."</p>";
    ob_end_flush();
    flush();
}
1 голос
/ 08 июня 2010
<?php
# try this...
for (;;) {
  echo time() . '<br>';
  ob_flush(); # http://php.net/ob_flush
  flush(); # http://php.net/flush
  sleep(1); # http://php.net/sleep
}
?>
1 голос
/ 08 июня 2010

Вы также можете иметь своего рода фоновое задание и интерфейс, дающий вам скорость прогресса.

например, страница с именем job.php

<?php
    for ($i=0; $i<100; ++$i)
    {
       store($i);
       // long stuff
       sleep(42);
    }
?>

и progress.php

<?php
      return get($i);
?>

Затем некоторые ajax-вызовы progress.php? Task = mytaskid и обновляют графический интерфейс. Я видел такой метод для «большой» загрузки файла и нашел его отличным.

Редактировать: извините, это не совсем отвечает на первоначальный вопрос.

...