복붙노트

각각의`echo` 호출 후에 어떻게 출력을 플러시합니까?

PHP

각각의`echo` 호출 후에 어떻게 출력을 플러시합니까?

나는 클라이언트에게만 로그를 생성하는 PHP 스크립트를 가지고있다. 내가 어떤 것을 울릴 때, 나는 그것을 클라이언트에게 즉시 전송하고 싶다. 스크립트가 처리되는 동안 페이지는 비어 있습니다. ob_start () 및 ob_flush ()를 사용하여 이미 놀았지만 작동하지 않았습니다.

가장 좋은 솔루션은 무엇입니까?

추신 : 그것은 에코 전화의 끝에 플러시를 넣어 조금 더러운 ...

편집 : 대답, PHP 또는 아파치 오류가 작동하지?

해결법

  1. ==============================

    1.편집하다:

    편집하다:

    매뉴얼 페이지에서 위의 내용을 읽었으며 ob_implicit_flush가 작동하지 않고 다음과 같은 해결 방법이 있다는 버그가 발견되었습니다.

    ob_end_flush();
    
    # CODE THAT NEEDS IMMEDIATE FLUSHING
    
    ob_start();
    

    무슨 일이 일어나고 있는지도 모르지만 서버가 보낼 가치가있는 패킷을 보낼 수있는 문자를 서버가 구축 할 때까지 클라이언트는 서버에서 패킷을받지 못합니다.

    이전 답변 :

    ob_implicit_flush를 사용하면 출력 버퍼링이 잠시 동안 버퍼링을 해제하도록 지시합니다.

    ob_implicit_flush(true);
    
    # CODE THAT NEEDS IMMEDIATE FLUSHING
    
    ob_implicit_flush(false);
    
  2. ==============================

    2.나는 같은 문제를 겪었고 매뉴얼에 게시 된 예제 중 하나가 효과가 있었다. 문자 세트는 이미 언급 한 포스터 중 하나로 지정해야합니다. http://www.php.net/manual/en/function.ob-flush.php#109314

    나는 같은 문제를 겪었고 매뉴얼에 게시 된 예제 중 하나가 효과가 있었다. 문자 세트는 이미 언급 한 포스터 중 하나로 지정해야합니다. 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 />';
    
  3. ==============================

    3.그래서 여기 내가 알아 낸 것이 있습니다.

    그래서 여기 내가 알아 낸 것이 있습니다.

    논리적으로, 그것은 gzip을하기 때문에 아파치의 mod_gzip이나 Nginx의 gzip에서는 flush가 작동하지 않을 것입니다. gzip을 사용하기 위해서는 내용을 버퍼링해야합니다. 웹 서버 gzipping의 어떤 종류든지 이것에 영향을 미칠 것입니다. 즉, 서버 측에서는 gzip을 비활성화하고 fastcgi 버퍼 크기를 줄여야합니다. 그래서:

    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);
    }
    
  4. ==============================

    4.겉으로보기에는 작동하지 않는 플러시는 자동 문자 세트 감지의 부작용입니다.

    겉으로보기에는 작동하지 않는 플러시는 자동 문자 세트 감지의 부작용입니다.

    브라우저는 문자 집합을 표시 할 때까지 아무 것도 표시하지 않으며 문자 집합을 지정하지 않으면 문자 집합을 추측하려고 시도합니다. 문제는 충분한 데이터없이 좋은 추측을 할 수 없다는 것인데, 이는 브라우저가 1024 바이트 (또는 비슷한) 버퍼를 갖고있는 것처럼 보이기 때문입니다.

    해결책은 브라우저가 문자 집합을 추측 할 필요가 없는지 확인하는 것입니다.

    텍스트를 보내는 경우 '; charset = utf-8 '을 내용 유형에 추가하고 HTML 인 경우 해당 메타 태그에 문자 집합을 추가하십시오.

  5. ==============================

    5.당신이 원하는 것은 flush 메소드입니다. 예:

    당신이 원하는 것은 flush 메소드입니다. 예:

    echo "log to client";
     flush();
    
  6. ==============================

    6.왜 이렇게 echo하는 함수를 만들지 않을까요?

    왜 이렇게 echo하는 함수를 만들지 않을까요?

    function fecho($string) {
     echo $string;
     ob_flush();
    }
    
  7. ==============================

    7.2018 년에 들어올 사람들을 위해 :

    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();
    ?>
    

    버퍼를 "채우는 것"으로 보이기 때문에 "4096"부분을 유지하는 것이 매우 중요합니다 ...

  8. ==============================

    8.나는 비슷한 일을했다. 사용

    나는 비슷한 일을했다. 사용

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

    내 경우에는 출력을 자주 내 보냅니다.

    하지만 특정 지점에서 출력을 바로 플러시해야했습니다 (루프가있는 상태에서 실행).

    ob_flush();
    flush();
    

    함께 나를 위해 일했다.

  9. ==============================

    9.사용할 올바른 함수는 flush ()입니다.

    사용할 올바른 함수는 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 바이트가되어야합니다.

  10. ==============================

    10.안티 바이러스 소프트웨어가 출력 플러싱을 방해 할 수도 있습니다. 제 경우 카스퍼 스키 안티 바이러스 2013은 허용 된 솔루션을 사용하고 있었지만 브라우저에 보내기 전에 데이터 청크를 보유하고있었습니다.

    안티 바이러스 소프트웨어가 출력 플러싱을 방해 할 수도 있습니다. 제 경우 카스퍼 스키 안티 바이러스 2013은 허용 된 솔루션을 사용하고 있었지만 브라우저에 보내기 전에 데이터 청크를 보유하고있었습니다.

  11. ==============================

    11.이 시도:

    이 시도:

    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 스크립트를 더 이상 리디렉션 할 수 없다는 것입니다. PHP가 스크립트 실행 http 헤더 당 한 번만 보낼 수 있기 때문입니다. 그러나 자바 스크립트를 사용하여 리디렉션 할 수 있습니다. 그냥 PHP 스크립트가 다음과 같은 라인을 에코하자 :

            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;
    
  12. ==============================

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

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

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

  13. ==============================

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

    이것은 내 코드입니다 : (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();
    }
    
  14. ==============================

    14.이것은 나를 위해 잘 작동합니다 (Apache 2.4 / PHP 7.0).

    이것은 나를 위해 잘 작동합니다 (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";
    
  15. ==============================

    15.때로는 문제가 아파치 설정에서 왔습니다. Apache는 출력을 gzip으로 설정할 수 있습니다. .htaccess 파일에서 다음과 같이 추가 할 수 있습니다.

    때로는 문제가 아파치 설정에서 왔습니다. Apache는 출력을 gzip으로 설정할 수 있습니다. .htaccess 파일에서 다음과 같이 추가 할 수 있습니다.

    SetEnv no-gzip 1
    
  16. ==============================

    16.나는 토론에 늦었지만 많은 사람들이 flush ()를 추가한다고 말하고있다. 각 코드의 끝에는 더러워 보입니다.

    나는 토론에 늦었지만 많은 사람들이 flush ()를 추가한다고 말하고있다. 각 코드의 끝에는 더러워 보입니다.

    가장 좋은 해결책은 아파치, 중간 핸들러 및 PHP에서 deflate, gzip 및 모든 버퍼링을 비활성화하는 것입니다. 그렇다면 php.ini 파일에 다음과 같은 내용이 있어야합니다.

                output_buffering = Off
                zlib.output_compression = Off
                implicit_flush = Off
    

    flush ()로 문제를 해결할 수 있다면 임시 해결책은 php.ini에 있습니다. 그러나 당신은 그것을 도처에 두는 것이 더럽고 추악하다고 생각합니다.

    implicit_flush = On
    

    php.ini 파일에 위 코드를 추가하면 flush ()를 넣을 필요가 없습니다. 더 이상 코드에서.

  17. from https://stackoverflow.com/questions/3133209/how-to-flush-output-after-each-echo-call by cc-by-sa and MIT license