Можно ли повторять каждый раз, когда цикл выполняется? Например:
foreach(range(1,9) as $n){
echo $n."\n";
sleep(1);
}
Вместо того, чтобы печатать все, когда цикл завершен, я бы хотел, чтобы он печатал каждый результат за раз.
Можно ли повторять каждый раз, когда цикл выполняется? Например:
foreach(range(1,9) as $n){
echo $n."\n";
sleep(1);
}
Вместо того, чтобы печатать все, когда цикл завершен, я бы хотел, чтобы он печатал каждый результат за раз.
Самый простой способ устранить буферизацию nginx — создать заголовок:
header('X-Accel-Buffering: no');
Это устраняет как proxy_buffering
, так и (если у вас nginx >= 1.5.6), fastcgi_buffering
. Бит fastcgi имеет решающее значение, если вы используете php-fpm. Заголовок также гораздо удобнее делать по мере необходимости.
Документы по X-Accel-Buffering Документы по fastcgi_buffering
set_time_limit(0)
, отправляя только этот заголовок, без заголовка типа контента, за которым следует мой эхо-код HTML (или require_once()), затем ob_flush()
, а затем flush()
. Затем я мог бы выполнить свою длинную задачу (задачу электронной коммерции), а затем вывести остальную часть HTML, когда закончу, чтобы закрыть страницу, которая добавляет некоторый Javascript, который немедленно перенаправляет страницу на получение их заказа.
- person Volomike; 24.04.2017
ОКОНЧАТЕЛЬНОЕ РЕШЕНИЕ
Итак, что я узнал:
Flush не будет работать под mod_gzip Apache или gzip Nginx, потому что, по логике, он сжимает содержимое, а для этого он должен буферизовать содержимое, чтобы сжать его. Любое сжатие веб-сервера повлияет на это. Короче говоря, на стороне сервера нам нужно отключить gzip и уменьшить размер буфера fastcgi. Так:
В php.ini:
. output_buffering = Выкл.
. zlib.output_compression = Выкл.
В nginx.conf:
. сжатие выключено;
. прокси_буферизация выключена;
Также имейте под рукой эти строки, особенно если у вас нет доступа к php.ini:
@ini_set('zlib.output_compression',0);
@ini_set('implicit_flush',1);
@ob_end_clean();
set_time_limit (0);
Наконец, если он у вас есть, прокомментируйте код ниже:
ob_start('ob_gzhandler');
ob_flush();
Тестовый код PHP:
ob_implicit_flush(1);
for($i=0; $i<10; $i++){
echo $i;
//this is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
sleep(1);
}
Связанный:
str_repeat(' ', 4096)."\n";
, чтобы убедиться, что контент отправлен.
- person Yvan; 17.11.2014
Простое решение на сервере nginx:
fastcgi_keep_conn on; # < solution
proxy_buffering off;
gzip off;
http
, server
или location
контекстах. Таким образом, вы можете быть очень избирательны, где это применимо.
- person Majid Fouladpour; 17.09.2019
Я не хотел отключать gzip для всего сервера или всего каталога, только для нескольких скриптов, в нескольких конкретных случаях.
Все, что вам нужно, это это, прежде чем что-либо будет эхом:
header('Content-Encoding: none;');
Затем выполните промывку как обычно:
ob_end_flush();
flush();
Nginx, кажется, улавливает, что кодировка отключена, и не сжимает.
header('X-Accel-Buffering: no');
.
- person kbtz; 24.08.2015
header('Content-Encoding: none;');
сработало для меня. Нет необходимости в ob_end_flush()
или flush()
, просто убедитесь, что вывод достаточно большой, используя echo str_repeat(' ', 1024*64);
- person ; 14.02.2017
Вам нужно сбросить буфер php в браузер
foreach(range(1,9) as $n){
echo $n."\n";
flush();
sleep(1);
}
См.: http://php.net/manual/en/function.flush.php а>
if(ob_get_level() > 0) ob_flush();
- person meze; 02.02.2011
ob_get_level
вернет 0, нет необходимости делать @-хаки.
- person meze; 02.02.2011
while (ob_get_level() > 0) ob_end_clean()
- person Petah; 02.02.2011
Я обнаружил, что вы можете установить:
header("Content-Encoding:identity");
в вашем php-скрипте, чтобы отключить сжатие nginx без необходимости изменять nginx.conf
Этого можно добиться, очистив выходной буфер в середине цикла.
Пример:
ob_start();
foreach(range(1,9) as $n){
echo $n."\n";
ob_flush();
flush();
sleep(1);
}
Обратите внимание, что ваши настройки php.ini могут повлиять на то, будет ли это работать или нет, если у вас включено сжатие zlib.
У меня возникла проблема с gzip из-за моего движка php-fpm. этот код единственный, который работает для меня:
function myEchoFlush_init() {
ini_set('zlib.output_compression', 0);
ini_set('output_buffering', 'Off');
ini_set('output_handler', '');
ini_set('implicit_flush', 1);
ob_implicit_flush(1);
ob_end_clean();
header('Content-Encoding: none;');
}
function myEchoFlush($str) {
echo $str . str_repeat(' ', ini_get('output_buffering') * 4) . "<br>\n";
}
Это моя тестовая функция: она проверяет max_execution_time:
public function timeOut($time = 1, $max = 0) {
myEchoFlush_init();
if ($max) ini_set('max_execution_time', $max);
myEchoFlush("Starting infinite loop for $time seconds. It shouldn't exceed : " . (ini_get('max_execution_time')));
$start = microtime(true);
$lastTick = 1;
while (true) {
$tick = ceil(microtime(true) - $start);
if ($tick > $lastTick) {
myEchoFlush(microtime(true) - $start);
$lastTick = $tick;
}
if ($tick > $time) break;
}
echo "OK";
}
myEchoFlush_init()
работал, за исключением того, что мне пришлось удалить из него заголовок.
- person Dellowar; 02.05.2019