It seems that while using output buffering, an included file which calls die() before the output buffer is closed is flushed rather than cleaned. That is, ob_end_flush() is called by default.
<?php
// a.php (this file should never display anything)
ob_start();
include('b.php');
ob_end_clean();
?>
<?php
// b.php
print "b";
die();
?>
This ends up printing "b" rather than nothing as ob_end_flush() is called instead of ob_end_clean(). That is, die() flushes the buffer rather than cleans it. This took me a while to determine what was causing the flush, so I thought I'd share.
출력 제어 함수
소개
출력 제어 함수는 스크립트의 출력 전송을 제어할 수 있도록 합니다. 이는 여러 상황에서, 특히 스크립트가 브라우저로 데이터를 출력한 뒤에 헤더를 전송할 필요가 있을 경우에 유용합니다. 출력 제어 함수는 header()나 setcookie()를 사용하는 헤더 전송에는 영향을 주지 않으며, echo() 등의 함수나 PHP 코드 블럭 사이의 데이터에만 적용됩니다.
요구 조건
이 확장을 빌드할 때 외부 라이브러리가 필요하지 않습니다.
설치
이 함수들은 설치하지 않아도 사용할 수 있습니다; PHP 코어의 일부입니다.
실행시 설정
이 함수의 작동은 php.ini 설정에 영향을 받습니다.
| 이름 | 기본값 | 설정권한 | 변경점 |
|---|---|---|---|
| output_buffering | "0" | PHP_INI_PERDIR | |
| output_handler | NULL | PHP_INI_PERDIR | PHP 4.0.4부터 사용할 수 있습니다. |
| implicit_flush | "0" | PHP_INI_ALL | PHP <= 4.2.3에서는 PHP_INI_PERDIR입니다. |
위 설정 지시어에 대한 간단한 설명입니다.
- output_buffering boolean/integer
-
이 지시어를 'On'으로 설정하여 모든 파일에 출력 버퍼링을 활성화 할 수 있습니다. 버퍼의 크기를 제한하려면 이 지시어의 값으로 'On' 대신 최대 바이트 수를 사용하십시오. (예. output_buffering=4096) PHP 4.3.5부터 PHP-CLI에서는 이 지시어가 항상 Off입니다.
- output_handler string
-
스크립트의 모든 출력을 어떤 함수를 통하게 할 수 있습니다. 예를 들면, output_handler를 mb_output_handler()로 설정하면, 문자 인코딩을 지정한 인코딩으로 변경할 수 있습니다. 출력 핸들러 설정은 자동적으로 출력 버퍼링을 켭니다.
Note: mb_output_hadler()와 ob_iconv_handler()를 동시에 사용할 수 없고, ob_gzhandler()와 zlib.output_compression도 동시에 사용할 수 없습니다.
Note: 이 지시어로는 내장 함수만 사용할 수 있습니다. 사용자 정의 함수에 대해서는 ob_start()를 사용하십시오.
- implicit_flush boolean
-
기본값으로 FALSE입니다. TRUE로 변경하면 PHP가 모든 출력 블럭 뒤에 바로 전송하도록 출력 레이어를 설정합니다. 이는 PHP 함수 flush()를 모든 printf(), echo(), HTML 블럭 뒤에 호출하는 것과 동일합니다.
PHP를 웹 환경에서 사용할 때, 이 옵션을 켜는 것은 심각한 성능 저하를 일으킵니다. 일반적으로 디버깅 목적으로만 사용할 것을 권장합니다. CLI SAPI에서는 기본값으로 TRUE입니다.
참고: ob_implicit_flush().
자원형
이 확장은 리소스형을 정의하지 않습니다.
예약 상수
이 확장은 상수를 정의하지 않습니다.
예제
Example#1 출력 제어 예제
<?php
ob_start();
echo "Hello\n";
setcookie("cookiename", "cookiedata");
ob_end_flush();
?>
위 예제에서, echo()의 출력은 ob_end_flush()를 호출할 때까지 출력 버퍼에 저장됩니다. 그리하여 setcookie() 호출은 에러를 발생하지 않고 성공적으로 쿠키를 저장합니다. (보통은 브라우저로 데이터를 전송한 뒤에 헤더를 전송할 수 없습니다)
Note: PHP 4.1(과 4.2)에서 4.3으로 업그레이드 할 때 이전 버전의 버그로 인해, php.ini에서 implict_flush가 OFF인지 확인해야만 합니다. 그렇지 않으면 ob_start()는 어떠한 출력도 숨기지 못합니다.
참고
참고: header(), setcookie().
Table of Contents
- flush — 출력 버퍼를 비웁니다.
- ob_clean — 출력 버퍼를 지웁니다.
- ob_end_clean — 출력 버퍼를 지우고 출력 버퍼링을 종료합니다.
- ob_end_flush — 출력 버퍼를 전송하고 출력 버퍼링을 종료합니다.
- ob_flush — 출력 버퍼를 전송합니다.
- ob_get_clean — 현재 버퍼 내용을 얻은 뒤에 현재 출력 버퍼를 지웁니다.
- ob_get_contents — 출력 버퍼의 내용을 반환합니다.
- ob_get_flush — Flush the output buffer, return it as a string and turn off output buffering
- ob_get_length — 출력 버퍼의 길이를 반환합니다.
- ob_get_level — 출력 버퍼링 메카니즘의 겹친 레벨을 반환합니다.
- ob_get_status — 출력 버퍼의 상태를 얻습니다.
- ob_gzhandler — gzip 출력 버퍼를 위한 ob_start 콜백 함수입니다.
- ob_implicit_flush — 절대 출력의 여부를 결정합니다.
- ob_list_handlers — List all output handlers in use
- ob_start — 출력 버퍼링을 켭니다.
- output_add_rewrite_var — Add URL rewriter values
- output_reset_rewrite_vars — Reset URL rewriter values
출력 제어
29-Jun-2007 07:02
28-Jan-2007 12:45
Please note that most browsers don't display a table unless they passed its end-tag "</table>".
Thats why using this feature in HTML-tables might not result in what you expected...
best regards
BasicArtsStudios
21-Jan-2007 10:39
Sometimes you might not want to include a php-file under the specifications defined in the functions include() or require(), but you might want to have in return the string that the script in the file "echoes".
Include() and require() both directly put out the evaluated code.
For avoiding this, try output-buffering:
<?php
ob_start();
eval(file_get_contents($file));
$result = ob_get_contents();
ob_end_clean();
?>
or
<?php
ob_start();
include($file);
$result = ob_get_contents();
ob_end_clean();
?>
which i consider the same, correct me if I'm wrong.
Best regards, BasicArtsStudios
16-Sep-2006 02:08
Unfortunately, the PHP guys didn't build support into any of the image output functions to return the image instead of outputting it.
Fortunately, we have output buffering to fix that.
<?
$im = imagecreatetruecolor(200, 200);
// Other image functions here...
ob_start();
imagepng($im);
$imageData = ob_get_contents();
ob_clean();
?>
You can now use the $imageData variable to either create another GD image, save it, put it in a database, make modifications to the binary, or output it to the user. You can easily check the size of it as well without having to access the disk...just use strlen();
07-Sep-2006 04:07
Now this just blew my mind. I had a problem with MySQL being incredibly slow on Windows 2003 running IIS... on ASP/VBScript pages. PHP is also installed on the server and so is Microsoft SQL 2005 Express. (Yes, we're running ASP, PHP, MySQL and MS SQL on the same Windows 2003 Server using IIS.)
I was browsing the internet for a solution and saw a suggestion that I change output_buffering to on if MySQL was slow for PHP pages. Since we also served PHP pages with MySQL from the same server, it caught my eye. For the hell of it, I went into php.ini and changed output_buffering to on and suddenly MySQL and ASP was faster... MySQL and PHP was faster... Microsoft SQL Server 2005 Express and ASP was faster.... everything was faster... even stuff that had no PHP!
And I didn't even have to restart IIS. As soon as I saved the php.ini file with the change, everything got faster.
Apparently PHP and MySQL and IIS are so intertwined somehow that changing the buffering setting really effects the performance of the entire server.
So, if you are having performance problems on Windows 2003 & IIS, you might try setting output_buffering = On in php.ini if you happen to have PHP installed. Having it set to off apparently effects the performance of Windows 2003 and IIS severely... even for webpages that do not use PHP or MySQL.
21-Aug-2006 01:30
Output buffering is set to '4096' instead of 'Off' or '0' by default in the php-5.0.4-10.5 RPM for Fedora Core release 4 (Stentz). This has cost me much time!
10-Jul-2006 06:00
In re to erwinX at darwineX dot nl:
Adding an ampersand (&) before the hash seems to work too (for me at least), i.e.: http://somedomain.tld/blah.php?arg=x&#something
I guess php then interperts it as an argument to the script. Might save some time and resources.
11-Nov-2005 05:35
[Concerns IE refusing to jump to a #something in the URL.]
I encoutered a bug in IE6/W2000 that can be solved by turning output buffering on.
Maybe it also helps in other situations/M$-OS, not sure.
Situation:
A page with a hash in the URL, and IE doesn't jump to that location.
Example:
http://www.bla.com/test.php#something
- In test.php the anchortag is placed normally like:
<a name="something"><br></a>
- test.php takes a few seconds to load because of heavy-duty database activity.
IE just ignores the hash #something.
It looks like IE 'forgets' the hash if it hasn't encoutered it YET in the HTML.
Turning output buffering on resolves that issue.
23-Jun-2005 11:25
I ran out of memory, while output buffering and drawing text on imported images. Only the top portion of the 5MP image was displayed by the browser. Try increasing the memory limit in either the php.ini file( memory_limit = 16M; ) or in the .htaccess file( php_value memory_limit "16M" ). Also see function memory_get_usage() .
10-Jul-2004 05:53
For those who are looking for optimization, try using buffered output.
I noticed that an output function call (i.e echo()) is somehow time expensive. When using buffered output, only one output function call is made and it seems to be much faster.
Try this :
<?php
your_benchmark_start_function();
for ($i = 0; $i < 5000; $i++)
echo str_repeat ("your string blablabla bla bla", (rand() % 4) + 1)."<br>\n";
echo your_benchmark_end_function();
?>
And then :
<?php
your_benchmark_start_function();
ob_start ();
for ($i = 0; $i < 5000; $i++)
echo str_repeat ("your string blablabla bla bla", (rand() % 4) + 1)."<br>\n";
echo your_benchmark_end_function();
ob_end_flush ();
?>
09-Jul-2003 04:44
Trying to benchmark your server when using output_buffering ?
Don't forget that the value 4096 in the php.ini will give you complete different loadtimes compares to the value of 1.
In the first case the output will be sent after buffering 4096 and the loadtime timed at the end of the page will contain the loadtime needed to download the complete page in the clientbrowser while the second value will contain the loadtime needed to place the complete page in the buffer. The time needed for sending is not clocked.
This can be very frustrating if you don't see the differance between server and the 1st is using 4096 instead of 1.
Although technically much faster than the second server the second server was providing much better loadtime results.
This result will grow when using large amounts of output.
But this becomes interesting if you want to measure the time needed for the page to be loaded for the client.
08-Feb-2001 11:17
A few tutorials exist on this subject :
* http://www.zend.com/zend/art/buffering.php
* http://www.phpbuilder.com/columns/argerich20010125.php3
