source

각 에코 콜 후에 출력을 플러시하려면 어떻게 해야 합니까?

lovecheck 2022. 12. 28. 21:42
반응형

각 에코 콜 후에 출력을 플러시하려면 어떻게 해야 합니까?

클라이언트에 대한 로그만 생성하는 php 스크립트가 있습니다.
에코를 할 때 클라이언트에 즉시 전송해 주었으면 합니다.
처리 이 되기 에) (「」 「」 「」 「」)
난난 around around와 .ob_start() ★★★★★★★★★★★★★★★★★」ob_flush()하지만 효과가 없었습니다.

어떻게 하면 좋을까요?

추신: 플래시를 붙이는 것은 조금 지저분합니다.echo★★★★★★★★★★★…

편집: PHP 또는 Apache 오류 중 어느 쪽도 응답하지 않았습니다.

같은 문제가 발생했는데 매뉴얼에 게재된 예시 중 하나가 작동했습니다.여기에 이미 언급된 포스터 중 하나로 문자 집합을 지정해야 합니다.http://www.php.net/manual/en/function.ob-flush.php#109314

header( 'Content-type: text/html; charset=utf-8' );
echo 'Begin ...<br />';
for( $i = 0 ; $i < 10 ; $i++ )
{
    echo $i . '<br />';
    flush();
    ob_flush();
    sleep(1);
}
echo 'End ...<br />';

편집:

메뉴얼의 코멘트를 읽다가, 다음과 같은 버그를 발견했습니다.ob_implicit_flush 는 동작하지 않습니다.이것에 대한 회피책은 다음과 같습니다.

ob_end_flush();

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_start();

이 방법으로 동작하지 않는 경우는, 송신할 가치가 있다고 생각되는 패킷을 송신할 수 있는 문자가 서버에 축적될 때까지, 클라이언트가 서버로부터 패킷을 수신하지 않는 경우가 있습니다.


오래된 답변:

를 사용하면 출력 버퍼링이 잠시 동안 버퍼링을 끄도록 지시할 수 있습니다.

ob_implicit_flush(true);

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_implicit_flush(false);

그래서 내가 알아낸 건 이거야.

flash는 Apache의 mod_gzip이나 Nginx의 gzip에서는 동작하지 않습니다.논리적으로 콘텐츠를 gzip 하기 위해서는 콘텐츠를 버퍼링해야 하기 때문입니다.모든 종류의 웹 서버 지핑이 여기에 영향을 미칩니다.즉, 서버 측에서는 gzip을 비활성화하여 fastcgi 버퍼 크기를 줄여야 합니다.그래서:

  • php.ini의 경우:

    output_buffering = Off
    
    zlib.output_compression = Off
    
  • nginx.conf의 경우:

    gzip  off;
    
    proxy_buffering  off;
    

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 to make the buffer achieve the minimum size in order to flush data
    echo str_repeat(' ',1024*64);

    sleep(1);
}

2018년 출시 예정자:

유일한 솔루션은 다음과 같습니다.

<?php

    if (ob_get_level() == 0) ob_start();
    for ($i = 0; $i<10; $i++){

        echo "<br> Line to show.";
        echo str_pad('',4096)."\n";    

        ob_flush();
        flush();
        sleep(2);
    }

    echo "Done.";

    ob_end_flush();
?>

de 4096 파트를 유지하는 것이 매우 중요합니다.완충재를 채우는 것 같기 때문입니다.

기능하지 않는 것처럼 보이는 플러시는 자동 문자 집합 검출의 부작용입니다.

브라우저는 표시할 문자 집합을 인식할 때까지 아무것도 표시하지 않으며, 문자 집합을 지정하지 않으면 추측을 시도해야 합니다.문제는 충분한 데이터가 없으면 제대로 추측할 수 없다는 것입니다. 그렇기 때문에 브라우저는 무언가를 표시하기 전에 이 1024바이트(또는 이와 유사한) 버퍼를 채워야 하는 것 같습니다.

따라서 브라우저가 문자 집합을 추측할 필요가 없도록 하는 것이 해결책입니다.

텍스트를 송신하는 경우는, 컨텐츠 타입에 「; charset=utf-8」을 추가하고, HTML 의 경우는 문자 세트를 적절한 메타 태그에 추가합니다.

당신이 원하는 것은 플러시 방식입니다.예:

echo "log to client";
 flush();

다음과 같이 에코하는 함수를 만들면 어떨까요?

function fecho($string) {
 echo $string;
 ob_flush();
}

저도 비슷한 일이 있었어요.사용.

// ini_set("output_buffering", 0);  // off 
ini_set("zlib.output_compression", 0);  // off
ini_set("implicit_flush", 1);  // on   

제 경우 출력 플러싱이 잦아졌습니다.

단, (실행하는 루프의) 특정 포인트에서 출력을 바로 플러시해야 했기 때문에 양쪽을 모두 사용합니다.

ob_flush();
flush();

다 같이 먹혔어요.

ini_set(...)를 사용하여 "output_buffering"을 끌 수 없어서 php.ini에서 직접 꺼야 했는데, phpinfo()를 끄면 "no value"로 설정이 표시되는데, 정상인가요?

자주 언급되지 않는 것은 다양한 호스팅 환경의 세부 사항 때문에 계속 켜져 있는 gzip 압축입니다.

다음은 PHP-FPM을 Fast CGI로 사용하는 최신 접근법입니다.이것은 .htaccess rewrite 규칙이나 환경변수를 필요로 하지 않습니다.

php.ini 또는 .user.ini의 경우:

output_buffering = 0
zlib.output_compression = 0
implicit_flush = true
output_handler = 

PHP 스크립트:

header('Content-Encoding: none'); // Disable gzip compression
ob_end_flush(); // Stop buffer
ob_implicit_flush(1); // Implicit flush at each output command

ob_end_flush() 니즈에 대해서는 공식 PHP 문서에서 이 코멘트를 참조하십시오.

사용하는 올바른 기능은 다음과 같습니다.flush().

<html>
<body>
<p>
Hello! I am waiting for the next message...<br />
<?php flush(); sleep(5); ?>
I am the next message!<br />
<?php flush(); sleep(5); ?>
And I am the last message. Good bye.
</p>
</body>
</html>

IE에는 256바이트 이상일 때만 플러시된 콘텐츠를 출력하는 "문제"가 있으므로 페이지의 첫 부분은 256바이트 이상이어야 합니다.

이것으로 문제없이 동작합니다(Apache 2.4/PHP 7.0).

@ob_end_clean();
echo "lorem ipsum...";
flush();
sleep(5);
echo "<br>dolor...";
flush();
sleep(5);
echo "<br>sit amet";
header( 'X-Accel-Buffering: no' );
header( 'Content-Type: text/html; charset=utf-8' );

echo 'text to display';
echo '<span style="display: none;">' . str_repeat ( ' ', 4096 ) . '</span>';
flush();
usleep( 10 );

안티바이러스 소프트웨어도 출력 플러싱을 방해할 수 있습니다.제 경우, Kaspersky Anti-Virus 2013은 승인된 솔루션을 사용했음에도 불구하고 브라우저로 전송하기 전에 데이터 청크를 보유하고 있었습니다.

Apache 설정에서 문제가 발생할 수 있습니다.Apache는 출력을 gzip하도록 설정할 수 있습니다..htaccess 파일에서 예를 추가할 수 있습니다.

SetEnv no-gzip 1

이것을 시험해 보세요.

while (@ob_end_flush());      
ob_implicit_flush(true);

echo "first line visible to the browser";
echo "<br />";

sleep(5);

echo "second line visible to the browser after 5 secs";

이렇게 하면 현재 스크립트의 출력 버퍼가 비활성화됩니다.ob_start()로 다시 활성화 할 수 있을 것 같습니다(잘 모르겠습니다).

위와 하면 더 를 리다이렉트할 수 입니다.header()php는 스크립트 실행 http 헤더당 한 번만 전송할 수 있기 때문입니다., javascript javascript를 할 수 .에 따라 .php 크 、 p 、 p 、 p 、 just just just just 。

        echo '<script type="text/javascript">';
        echo 'window.location.href="'.$url.'";';
        echo '</script>';
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
        echo '</noscript>'; 
        exit;

Dreamhost와 같은 특정 공유 호스팅 사이트에 있는 경우 다른 경로를 거치지 않고는 PHP 출력 버퍼링을 비활성화할 수 없습니다.

출력 버퍼 캐시 변경 PHP Fast CGI를 사용하는 경우 PHP 함수 flush(), ob_flush() 및 ob_implicit_flush()는 예상대로 작동하지 않습니다.기본적으로는 출력은 PHP보다 높은 수준에서 버퍼링됩니다(구체적으로는 mod_gzip과 형태/함수가 유사한 Apache 모듈 mod_deflate).

버퍼링되지 않은 출력이 필요한 경우 (Fast CGI가 아닌) CGI를 사용하거나 지원 센터에 문의하여 mod_deflate가 사용 중인 사이트에서 비활성화되도록 요청해야 합니다.

https://help.dreamhost.com/hc/en-us/articles/214202188-PHP-overview

토론이 늦었지만 많은 사람들이 flash()를 추가한다고 말하고 있는 것을 읽었습니다.각 코드 끝은 더러워 보이고, 그들은 옳습니다.

가장 좋은 해결책은 Apache, 중간 핸들러 및 PHP에서 deflate, gzip 및 모든 버퍼링을 비활성화하는 것입니다.그 후 php.ini에는 다음과 같은 것이 있습니다.

            output_buffering = Off
            zlib.output_compression = Off
            implicit_flush = Off

일시적인 해결책은 이것을 php.ini에 저장하는 것입니다.flush()로 문제를 해결할 수 있지만, 그것을 어디에나 두는 것은 더럽고 추하다고 생각됩니다.

implicit_flush = On

위의 php.ini에만 입력하면 flash();를 코드에 넣을 필요가 없습니다.

이것은 제 코드입니다: (PHP7에서 동작)

private function closeConnection()
{
    @apache_setenv('no-gzip', 1);
    @ini_set('zlib.output_compression', 0);
    @ini_set('implicit_flush', 1);

    ignore_user_abort(true);
    set_time_limit(0);

    ob_start();
    // do initial processing here
    echo json_encode(['ans' => true]);

    header('Connection: close');
    header('Content-Length: ' . ob_get_length());
    ob_end_flush();
    ob_flush();
    flush();
}

언급URL : https://stackoverflow.com/questions/3133209/how-to-flush-output-after-each-echo-call

반응형