Эхо-сообщения, пока скрипт php все еще выполняется

У меня есть php-скрипт, который использует cURL и выполняется около 10-15 минут. Что он делает, он анализирует около 1000 страниц в поисках конкретных совпадений, и по всему сценарию у меня выводятся диагностические сообщения, такие как «Переход к следующей странице», «Найдено совпадение», «Ошибка загрузки страницы»... то, как это работает сейчас (и то, как это нормально), выполняется примерно 10 минут и только затем выдает все мои пользовательские сообщения. Я хотел бы иметь возможность отображать эти сообщения по мере их появления, а не после завершения выполнения сценария. Я думал, что это сделает что-то вроде AJAX, но не уверен, как это будет работать. Любые советы приветствуются. Спасибо.


person pHelics    schedule 12.01.2011    source источник
comment
Аналогично этому вопросу.   -  person netcoder    schedule 12.01.2011
comment
Еще одним простым случаем может быть выполнение скрипта из командной строки, таким образом вы получите эхо в режиме реального времени.   -  person Poelinca Dorin    schedule 12.01.2011


Ответы (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 секунду. В противном случае скрипт будет работать слишком быстро, и мы не сможем знать, достигли ли мы цели. Надеюсь это поможет !

person Bogdan    schedule 23.05.2012

Вы можете создать промежуточную таблицу.

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

Затем вы можете периодически опрашивать отдельный PHP-скрипт с помощью ajax, который будет запрашивать таблицу и возвращать клиенту любые новые сообщения.

person Mads Mogenshøj    schedule 12.01.2011
comment
Согласованный. Флеш не сработает в 100% случаев. Аякс нужен. - person mrbinky3000; 12.01.2011
comment
Нет ли push-решения (вместо опроса)? - person richardaum; 24.11.2014

Используйте flush, чтобы немедленно отправить вывод в браузер, очистив буфер вывода.

echo "foo";
flush();
echo "bar";
flush();
person karim79    schedule 12.01.2011
comment
Flush не гарантирует работу во всех браузерах/платформах/конфигурациях. - person mrbinky3000; 12.01.2011

На самом деле вы ищете что-то вроде flush и ob_flush, однако имейте в виду, что существует множество факторов, которые могут помешать сбросу вашего вывода в тот момент, когда это происходит.

Из документации flush вы получите:

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

Модули сервера для Apache, такие как mod_gzip, могут выполнять собственную буферизацию, из-за которой метод flush() не приведет к немедленной отправке данных клиенту.

person acm    schedule 12.01.2011
comment
Вы правильно заметили, пока скрипт не будет готов, я работаю над ним на платформе Win32, затем я перенесу его на unix. - person pHelics; 12.01.2011

Я использую @ob_flush() после каждого echo. В этом примере PHP_EOL создает новую строку после $string

function output($string){
    echo $string.PHP_EOL;
    @ob_flush();
}
person Walter White    schedule 20.02.2016

По сути, пусть ваш скрипт записывает выходные данные HTML во временный файл журнала. Затем используйте ajax для периодического обновления браузера конечного пользователя временным файлом журнала. jQuery быстро с этим справится.

Ajax — единственный гарантированный способ заставить его работать во всех браузерах. Вот цитата со страницы сброса PHP.

flush() возможно, не сможет переопределить схему буферизации вашего веб-сервера и не повлияет на какую-либо буферизацию на стороне клиента в браузере. Это также не влияет на механизм буферизации вывода пользовательского пространства PHP. Это означает, что вам придется вызывать как ob_flush(), так и flush(), чтобы сбросить буферы вывода ob, если вы их используете.

person mrbinky3000    schedule 12.01.2011
comment
а если на страницу будет одновременно заходить 1000 пользователей с разными параметрами? , вам нужно будет написать 1000 файлов, я не рассматриваю это как вариант. - person Poelinca Dorin; 12.01.2011
comment
Вы можете легко создавать временные файлы в PHP. Это в основном то же самое, что и 1000 пользователей, которые вставляют данные в базу данных mysql. Черт возьми, используйте mysql. Просто сохраните журнал где-нибудь и привяжите его к этому сеансу, если его использует более одного человека. У меня такое ощущение, что это внутренний скрипт, который будет использовать один человек. - person mrbinky3000; 12.01.2011

Похоже, у вас включена буферизация вывода.

Вызов ob_end_flush() напечатает то, что в данный момент находится в буфере. и отключите буфер для выполнения остальной части скрипта.

person Craige    schedule 12.01.2011

Вы можете использовать функцию flush() для отправки всего содержимого буфера клиенту. http://php.net/manual/fr/function.flush.php

person N. Hodin    schedule 12.01.2011

Вы можете использовать как 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.

person T30    schedule 17.11.2015