PHP 버퍼 ob_flush () 대 flush ()


79

ob_flush()과 의 차이점은 무엇 flush()이며 왜 둘 다 전화해야합니까?

ob_flush()참조 말한다 :

이 함수는 출력 버퍼 (있는 경우)의 내용을 보냅니다.

flush()참조 말한다 :

PHP의 쓰기 버퍼와 PHP가 사용하는 모든 백엔드 (CGI, 웹 서버 등)를 플러시합니다.

그러나 계속해서 다음과 같이 말합니다.

[it] 웹 서버의 버퍼링 스키마를 무시하지 못할 수 있습니다…

그래서 나는 ob_flush()항상 사용할 수 있다고 생각합니다 . 그러나 그렇게하면 이상한 결과가 나옵니다. 누군가 여기서 무슨 일이 일어나고 있는지 간단한 용어로 설명 할 수 있습니까?

답변:


75

ob_flush응용 프로그램에서 시작된 버퍼를 보냅니다. ob_start()PHP 스크립트 에는 여러 개의 중첩이있을 수 있습니다 . ob_flush현재 콘텐츠를 상위 레이어로 전달합니다.

PHP 자체는 (자체 재량에 따라) 버퍼 출력을 할 수 있습니다. 이것은 백엔드에 따라 다릅니다. 그러나 일반적으로 FastCGI자체 소켓 버퍼가 있습니다. 따라서 flush()현재 콘텐츠를 웹 서버로 보내기 위해 호출해야합니다.

그리고 이제 웹 서버는 mod_deflate사용자가 영향을 미치지 않는 다른 버퍼링 체계 ( 또는 콘텐츠 필터)를 자체적으로 구현할 수 있습니다 . 그러나 이것은 특별히 구성해야하므로 거의 발생하지 않습니다.

어쨌든 둘 다 사용하십시오.


11
ob_flush와 flush를 사용하고 순서대로 사용하십시오.
Robino

17
이 답변에서 누락 된 중요한 세부 사항은 output_buffering구성 옵션으로, php.ini 프로덕션 버전의 기본값은 4096입니다. 즉, PHP 스크립트가 시작되면 출력의 처음 4096 바이트가 버퍼링됩니다 (를 사용하여 플러시 할 수있는 버퍼에서 ob_flush()). 그것을 사용할 필요 이유입니다 ob_flush()뿐만 아니라 flush(). 비활성화 output_bufferingphp.ini 파일을 통해 또는 전화 ob_end_clean()또는 ob_end_flush()스크립트의 시작은이 필요성을 제거합니다.
Mark Amery

감사합니다 @MarkAmery, 그러나 ob_end_clean()"스크립트의 시작"에서 반 직관적 인 것처럼 보입니다. ob_start()두 번의 플러시 전후에 이것을 포함시켜야한다는 뜻 입니까?
Khom Nazid

그런데 나는이 ob_start()과를 ob_end_clean()매우 스크립트의 시작에. 그런 다음 스크립트 중 "echo"뒤에를 포함 ob_flush(); flush();합니다. 스크립트가 시간이 걸리는 동안 지금까지 수행 된 모든 작업이 화면 (브라우저)에 출력 될 것으로 예상합니다. 그러나 끝까지 아무것도 나오지 않습니다. 내가 무엇을 놓치고 있습니까?
Khom Nazid

1
@KhomNazid 브라우저 관찰은 HTTP 스트림 디버깅과 동일하지 않습니다. 불완전한 HTML DOM에 대한 증분 및 지연 출력은 표시되지 않을 수 있습니다. 현재 설정으로 일부 CLI 테스트를 수행하십시오. (그리고, 오직 다음, 그것에 대해 다른 질문을 시작합니다.)
마리오

33

ob_flush다음 과 같은 함수로 만든 출력 버퍼 플러시합니다.ob_start

flush PHP 스크립트 자체의 버퍼링 된 출력을 호출자에게 플러시합니다.


25

ob_flush()높은 수준의 플러시입니다. 높은 수준의 버퍼를 플러시하고 모든 콘텐츠를 보낼 준비가 된 낮은 수준의 내부 버퍼에 넣습니다.

  • 것을 주 ob_기능의 가족이 만드는 스택 , 그래서 그냥 맹목적으로 쓰기 버퍼를 ob_flush()어디서나 실제로 코드가이 스택을 활용 작성된 경우 "이상한 결과"를 제공하는 것입니다.

flush() 낮은 수준의 플러시로 PHP가 내부의 낮은 수준의 데이터 버퍼를 플러시하도록 지시합니다.

그 아래에는 소켓 계층 버퍼가 있습니다. 그 아래에는 네트워크 계층 버퍼가 있습니다. 그리고 가장 낮은 수준에서 데이터 케이블을 따라 내려가는 전자의 대기열입니다.


그런데 나는이 ob_start()과를 ob_end_clean()매우 스크립트의 시작에. 그런 다음 스크립트 중 "echo"뒤에를 포함 ob_flush(); flush();합니다. 스크립트가 시간이 걸리는 동안 지금까지 수행 된 모든 작업이 화면 (브라우저)에 출력 될 것으로 예상합니다. 그러나 끝까지 아무것도 나오지 않습니다. 내가 무엇을 놓치고 있습니까?
Khom Nazid

중간 단계로 @KhomNazid 버퍼링, 웹 서버, 프록시, 브라우저 ... 같은
궤도의 밝기 경주

11

나는 이것이 이전 질문 과 관련이 있다고 생각합니다 . 출력 버퍼링 사용의 중요한 이점은 데이터 압축과 함께 사용할 때입니다. 을 사용하지 않으면 ob_gzhandler얻을 것이 거의 없습니다 . flush단독으로 서버에있는 출력 데이터를 커밋합니다. 으로 ob_start그 대응 ob_flush, ob_end_clean그리고 ob_end_flush, 어떤 압축을 기다리고 있습니다 (봐 flushob_flush다른 버킷을 참조로 - ob에 데이터를 전송 flush, flush브라우저에 데이터를 전송 - 정확하지만 그건 생각하지 않을 수 있습니다) 싸서 클라이언트로 전송됩니다 .


감사합니다. 버킷 비유가 좋은 예입니다.
Ben
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.