У меня есть php-скрипт, который использует cURL и выполняется около 10-15 минут. Что он делает, он анализирует около 1000 страниц в поисках конкретных совпадений, и по всему сценарию у меня выводятся диагностические сообщения, такие как «Переход к следующей странице», «Найдено совпадение», «Ошибка загрузки страницы»... то, как это работает сейчас (и то, как это нормально), выполняется примерно 10 минут и только затем выдает все мои пользовательские сообщения. Я хотел бы иметь возможность отображать эти сообщения по мере их появления, а не после завершения выполнения сценария. Я думал, что это сделает что-то вроде AJAX, но не уверен, как это будет работать. Любые советы приветствуются. Спасибо.
Эхо-сообщения, пока скрипт php все еще выполняется
Ответы (9)
Итак, это старый пост, но я нашел решение для этого. Поскольку мне тоже нужно сделать то же самое, вывести, когда скрипт все еще работает. Ни один ответ отсюда не помог. Прежде всего, я использую сервер Win32 (производство) и XAMPP в качестве локального для тестов. Этот пример является лишь доказательством концепции и может быть изменен по вашему желанию.
<?php
ob_implicit_flush(true);
for($i=1; $i<=10; $i++){
echo "$i ...<br>";
for($k = 0; $k < 40000; $k++) echo ' ';
sleep(1);
}
?>
Итак, мы открываем выходной буфер как неявный. Затем мы делаем демонстрационный цикл для подсчета от 1 до 10 и отображаем значения по мере их обработки. Второй цикл заполнит буфер браузера. И, наконец, чтобы проверить, все ли работает, делаем сон на 1 секунду. В противном случае скрипт будет работать слишком быстро, и мы не сможем знать, достигли ли мы цели. Надеюсь это поможет !
Вы можете создать промежуточную таблицу.
PHP-скрипт мог бы вместо того, чтобы повторять сообщение, сохранять их в таблице базы данных (возможно, в таблице памяти для повышения производительности).
Затем вы можете периодически опрашивать отдельный PHP-скрипт с помощью ajax, который будет запрашивать таблицу и возвращать клиенту любые новые сообщения.
Используйте flush
, чтобы немедленно отправить вывод в браузер, очистив буфер вывода.
echo "foo";
flush();
echo "bar";
flush();
На самом деле вы ищете что-то вроде flush и ob_flush, однако имейте в виду, что существует множество факторов, которые могут помешать сбросу вашего вывода в тот момент, когда это происходит.
Из документации flush вы получите:
Некоторые серверы, особенно на Win32, по-прежнему будут буферизовать вывод вашего скрипта до тех пор, пока он не завершится перед передачей результатов в браузер.
Модули сервера для Apache, такие как mod_gzip, могут выполнять собственную буферизацию, из-за которой метод flush() не приведет к немедленной отправке данных клиенту.
Я использую @ob_flush()
после каждого echo
. В этом примере PHP_EOL
создает новую строку после $string
function output($string){
echo $string.PHP_EOL;
@ob_flush();
}
По сути, пусть ваш скрипт записывает выходные данные HTML во временный файл журнала. Затем используйте ajax для периодического обновления браузера конечного пользователя временным файлом журнала. jQuery быстро с этим справится.
Ajax — единственный гарантированный способ заставить его работать во всех браузерах. Вот цитата со страницы сброса PHP.
flush() возможно, не сможет переопределить схему буферизации вашего веб-сервера и не повлияет на какую-либо буферизацию на стороне клиента в браузере. Это также не влияет на механизм буферизации вывода пользовательского пространства PHP. Это означает, что вам придется вызывать как ob_flush(), так и flush(), чтобы сбросить буферы вывода ob, если вы их используете.
Похоже, у вас включена буферизация вывода.
Вызов ob_end_flush() напечатает то, что в данный момент находится в буфере. и отключите буфер для выполнения остальной части скрипта.
Вы можете использовать функцию flush() для отправки всего содержимого буфера клиенту. http://php.net/manual/fr/function.flush.php
Вы можете использовать как flush
, так и ob_flush
, напоминая о необходимости установить заголовок типа контента:
<?php
header( 'Content-type: text/html; charset=utf-8' );
for( $i = 0 ; $i < 10 ; $i++ ){
echo $i . '<br>';
flush();
ob_flush();
sleep(1);
}
Источник: примечание dermeister на странице php.net ob_flush.
Протестировано на Firefox 42.0 и Chrome 46.0.