>  기사  >  백엔드 개발  >  PHP_php 기술의 output_buffering에 대한 자세한 소개

PHP_php 기술의 output_buffering에 대한 자세한 소개

WBOY
WBOY원래의
2016-05-16 20:35:261342검색

저는 개인적으로 출력 버퍼링이 비교적 순수한 4.0 기능이라고 생각합니다. 개념적으로는 매우 간단하지만 출력 버퍼링은 매우 강력하며 개발자가 고급의 효율적인 프로그램을 보다 쉽게 ​​개발할 수 있도록 해줍니다.

이 기사에서는 HTTP 헤더를 소개하고, 출력 버퍼링이 HTTP 헤더 처리에 어떻게 도움이 되는지, 그리고 출력 버퍼링의 몇 가지 고급 사용법을 소개합니다.

HTTP 헤더

HTTP 프로토콜을 사용하여 설정된 모든 요청에 ​​대해 웹 서버에서 생성된 응답은 일반적으로 헤더와 본문의 두 부분으로 구성됩니다. 예를 들어 웹 서버의 문서 루트 디렉터리에 example.txt라는 작은 텍스트 파일이 있고 파일에 Hello, world!라는 텍스트가 포함되어 있는 경우 이 파일에 대한 HTTP 요청 응답은 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

HTTP/1.1 200 OK
날짜: 2000년 9월 2일 토요일 21:40:08 GMT
서버: Apache/1.3.11(Unix) mod_macro/1.1.1 PHP/4.0.2-dev
최종 수정: 2000년 9월 2일 토요일 21:39:49 GMT
E태그: "12600b-e-39b173a5"
허용 범위: 바이트
내용 길이: 14
연결: 닫기
콘텐츠 유형: 텍스트/일반
안녕하세요, 세상!

이 요청의 첫 번째 부분(더 큰 부분)은 HTTP 헤더입니다. HTTP 헤더는 브라우저에서 사용자에게 표시되지 않지만 문서 내용 유형, 사용된 프로토콜 버전, 문서가 마지막으로 수정된 날짜 등과 같은 브라우저에 대한 정보를 포함합니다. HTTP 헤더에는 규칙이 많지 않습니다. 일반적으로 형식은 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

필드: 값[필드: 값]

문서 본문과 빈 줄로 구분해야 합니다.

이 HTTP 헤더의 정보는 PHP 스크립트에서 추가하거나 변경할 수 있습니다. 예를 들어, header() 함수를 사용할 수 있습니다:

코드 복사 코드는 다음과 같습니다.

header("위치: http://www.php.net/"); // http://www.php.net/으로 리디렉션

SetCookie() 함수를 사용할 수도 있습니다.

코드 복사 코드는 다음과 같습니다.

SetCookie("foo", "bar");

HTTP 쿠키는 HTTP 헤더를 사용하여 구현된다는 것을 알고 계실 것입니다. 예를 들어 다음 PHP 파일

에 대한 HTTP 요청 응답은 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

SetCookie("foo", "bar");
"쿠키 설정"을 인쇄합니다.
?>

다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

HTTP/1.1 200 OK
날짜: 2000년 9월 2일 토요일 21:43:02 GMT
서버: Apache/1.3.11(Unix) mod_macro/1.1.1PHP/4.0.2-dev
X-Powered-By: PHP/4.0.2-dev
쿠키 설정: foo=bar
연결: 닫기
콘텐츠 유형: 텍스트/html
쿠키를 설정하세요.

브라우저는 서버에서 반환된 HTTP 헤더를 읽고 foo(이 경우 세션 쿠키)라는 쿠키가 전송되었음을 알고 그 값은 bar입니다.

출력 버퍼링 기술을 사용하는 이유

출력 버퍼링 기술의 필요성은 PHP/FI 2.0부터 분명했습니다. 이 버전의 PHP를 사용해 본 적이 있다면 헤더가 전송된 후 SetCookie가 호출되었다는 오류 메시지가 자주 표시되어 머리를 긁적이며 그 이유가 무엇인지 궁금했던 것을 기억하실 것입니다.

최신 버전의 PHP(PHP 3.0 또는 PHP 4.0)를 사용했다면 다음 오류 메시지를 보게 될 것입니다. 죄송합니다. 헤더가 전송된 후 php_set_cookie가 호출되었습니다. 또는 PHP의 header() 함수를 호출하려고 할 때 헤더 정보를 추가할 수 없습니다 - 헤더가 이미 전송되었습니다라는 메시지가 나타날 수 있습니다. 일반적으로 출력 버퍼링 기술 사용자는 이러한 성가신 오류 메시지를 피하는 반면 개발자는 고급 목적으로 사용할 수도 있습니다.

이러한 오류는 언제 발생했습니까? 이러한 오류 메시지는 HTTP 헤더가 전송된 후 헤더 정보를 추가하거나 수정하려고 할 때, 문서 본문과 헤더 사이에 빈 줄이 부족한 경우 발생할 수 있습니다. 이것이 어떻게 발생하는지 이해하기 위해 PHP가 HTTP 헤더 출력과 본문 출력을 처리하는 방법을 살펴보겠습니다.

스크립트가 실행되면 헤더 정보와 본문 정보를 동시에 보낼 수 있습니다.

헤더 정보(header() 또는 SetCookie() 함수에서)는 즉시 전송되지 않고 목록에 저장됩니다.

이렇게 하면 기본 헤더(예: Content-Type 헤더)를 포함한 헤더 정보를 수정할 수 있습니다. 그러나 스크립트가 헤더가 아닌 출력(예: 블록 또는 print() 호출 사용)을 보내면 PHP는 먼저 모든 헤더를 보낸 다음 빈 줄을 보내 HTTP 헤더를 종료하고 그 이후에만 계속해야 합니다. 신체 데이터를 보내세요. 이 시점부터 헤더 정보를 추가하거나 수정하려는 시도는 허용되지 않으며 위의 오류 메시지 중 하나가 전송됩니다.

이는 큰 문제를 일으키지 않지만 때로는 입력을 보내기 전에 HTTP 헤더를 종료하여 스크립트 논리를 복잡하게 만드는 경우도 있습니다. 출력 버퍼링 기술은 이러한 문제를 해결할 수 있습니다.

출력 버퍼링 작동 방식

출력 버퍼링이 활성화되면 스크립트가 출력을 보낼 때 PHP는 HTTP 헤더를 보내지 않습니다. 대신, 이 출력을 동적으로 증가하는 캐시로 연결합니다(중앙 집중식 출력 메커니즘이 있는 PHP 4.0에서만 사용 가능). 헤더가 실제로 전송되지 않으므로 여전히 헤더 행을 수정, 추가하거나 쿠키를 설정할 수 있습니다. 가장 간단한 경우, 스크립트가 종료되면 PHP는 자동으로 HTTP 헤더를 브라우저에 보낸 다음 출력 버퍼의 내용을 보냅니다. 간단합니다.

기본 사용법

출력 버퍼링을 제어하는 ​​데 도움이 되는 다음 네 가지 기능을 사용할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

ob_start()

출력 버퍼링 메커니즘을 활성화합니다.

출력 버퍼링은 여러 수준을 지원합니다. 예를 들어 ob_start() 함수는 여러 번 호출될 수 있습니다.

ob_end_flush()

출력 버퍼를 보내고 출력 버퍼링 메커니즘을 비활성화합니다.

ob_end_clean()

보내지 않고 출력 버퍼를 지우고 출력 버퍼링을 비활성화합니다.

ob_get_contents()

현재 출력 버퍼를 문자열로 반환합니다. 스크립트에서 내보낸 모든 출력을 처리할 수 있습니다.

또한 php.ini의 output_buffering 지시어를 활성화할 수 있습니다. 이 지시어가 활성화되면 각 PHP 스크립트는 처음에 ob_start() 함수를 호출하는 것과 동일합니다.

예시 1

코드 복사 코드는 다음과 같습니다.


예 1


"안녕하세요, $user"를 인쇄하세요.
SetCookie("와우", "이 쿠키는 이미 출력을 내보냈는데도 설정되었습니다!");
?>

여기서 출력을 보냈더라도(HTML 코드 블록 및 print 문에서) 출력 버퍼링 메커니즘 덕분에 오류 없이 SetCookie() 호출을 계속 사용할 수 있습니다. 이 목적으로 출력 버퍼링 메커니즘을 사용하면 특정 성능 저하가 발생하므로 기본적으로 이 메커니즘을 활성화하지 않는 것이 가장 좋습니다. 그러나 보다 복잡한 스크립트의 경우 출력 버퍼링을 통해 논리를 단순화할 수 있습니다.

예시 2

코드 복사 코드는 다음과 같습니다.

ob_start();
print "문자열의 길이를 계산하는 아주 멍청한 방법이 있습니다.";
$length = strlen(ob_get_buffer());
ob_end_clean();
?>

이 예는 문자열 길이를 결정하는 비효율적인 방법을 보여줍니다. 이는 단순히 strlen() 함수에 의해 처리되는 것이 아니라 먼저 출력 버퍼링 메커니즘을 활성화하고 문자열을 인쇄한 다음 출력 버퍼의 길이를 결정합니다. 마지막으로 출력 버퍼를 지우고(보내지 않음) 출력 버퍼링 메커니즘을 비활성화합니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.