PHP Problema de liberação de buffer de saída no Apache / Linux

6

Estou tendo problemas com o buffer de saída do PHP em meu servidor web Linux. O buffer de saída é mantido corretamente e todos os dados corretos são enviados para ele no meu código, mas os mecanismos normais de limpeza não são liberados no navegador. Eu tentei de tudo postado aqui: link mas sem sucesso até agora.

Eu tenho um pequeno script do php.net para testá-lo:

<?php
    ob_start();
    for($i=0;$i<70;$i++)
    {
        echo 'printing...<br />';
        ob_get_flush();
        flush();
        usleep(300000);
    }
?>

Isso deve imprimir "imprimindo ..." no navegador 70 vezes, uma linha a cada três segundos. Isso funciona bem no meu outro ambiente de teste que é baseado no Windows (ainda usando o pacote XAMPP, apache), mas no meu servidor Linux não. Ele aguarda o script terminar antes de dar qualquer coisa ao navegador, basicamente ignorando o comando flush inteiro.

Se alguém já experimentou isso antes ou sabe de algo que poderia ajudar (seja configuração do servidor ou ajuste de código), seria muito apreciado!

    
por Iiro Vaahtojärvi 03.05.2010 / 13:58

3 respostas

2

Eu tive esse problema e descobri que as linhas:

while ( @ob_end_flush() ); // even if there is no nested output buffer
flush();

resolveria o problema.

Os resultados podem variar. Isso funciona no meu sistema com o IE e o Apache 2.0.55.

Jeff

    
por 07.03.2011 / 03:10
1

Liberar o buffer de saída do PHP e liberar o buffer do Apache são duas tarefas diferentes. Muitas vezes acontece que você libera o buffer de saída do PHP, mas nada é enviado para o navegador pelo Apache até que haja mais dados. Além disso, às vezes, o navegador não exibe nada até receber dados suficientes. O que você pode tentar é "pad" sua saída com novas linhas.

Existem dois outros problemas com o código que você postou. Primeiro, ele inicia o buffer de saída uma vez e, em seguida, termina várias vezes no loop. Você também quer armazenar o buffer de saída dentro do loop ou pode simplesmente omiti-lo. O outro problema é que ob_get_flush() retornará o conteúdo do buffer de saída como uma string, e não o ecoará.

Tente este código:

<?php
    for($i=0;$i<70;$i++)
    {
        echo 'printing...<br />';
        echo str_repeat("\n",1024);
        flush();
        usleep(300000);
    }
?>

Do Manual do PHP:

flush() may not be able to override the buffering scheme of your web server and it has no effect on any client-side buffering in the browser. [...]

Server modules for Apache like mod_gzip may do buffering of their own that will cause flush() to not result in data being sent immediately to the client.

Even the browser may buffer its input before displaying it. Netscape, for example, buffers text until it receives an end-of-line or the beginning of a tag, and it won't render tables until the tag of the outermost table is seen.

Some versions of Microsoft Internet Explorer will only start to display the page after they have received 256 bytes of output, so you may need to send extra whitespace before flushing to get those browsers to display the page.

Meu exemplo tenta contornar isso enviando 1024 novas linhas.

    
por 03.05.2010 / 14:05
1

Como observado na documentação do PHP, uma causa comum para isso na minha experiência é o buffer de saída do mod_gzip no Apache. Muitas distribuições têm isso habilitado por padrão agora.

Marcar

    
por 25.08.2010 / 01:30