2024 日本 PHP 研討會

ob_end_clean

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_end_clean清除(擦除)作用中輸出緩衝區的內容並關閉它

說明

ob_end_clean(): 布林值

此函式會呼叫輸出處理程式(使用 PHP_OUTPUT_HANDLER_CLEANPHP_OUTPUT_HANDLER_FINAL 旗標),捨棄其傳回值,捨棄作用中輸出緩衝區的內容,並關閉作用中輸出緩衝區。

如果沒有使用 PHP_OUTPUT_HANDLER_REMOVABLE 旗標啟動的作用中輸出緩衝區,ob_end_clean() 將會失敗。

即使作用中輸出緩衝區是在沒有 PHP_OUTPUT_HANDLER_CLEANABLE 旗標的情況下啟動的,ob_end_clean() 也會捨棄其內容。

參數

此函式沒有參數。

傳回值

成功時返回 true,失敗時返回 false

錯誤/例外

如果函式失敗,它會產生一個 E_NOTICE

範例

以下範例顯示了一個清除作用中輸出緩衝區內容的簡單方法

範例 #1 ob_end_clean() 範例

<?php
ob_start
();
echo
'不會顯示的文字。';
ob_end_clean();
?>

參見

  • ob_start() - 開啟輸出緩衝
  • ob_get_contents() - 返回輸出緩衝區的內容
  • ob_clean() - 清除(擦除)作用中輸出緩衝區的內容
  • ob_get_clean() - 取得作用中輸出緩衝區的內容並關閉它
  • ob_end_flush() - 刷新(發送)作用中輸出處理程序的返回值,並關閉作用中輸出緩衝區

新增註釋

使用者提供的註釋 11 則註釋

Sam Yong - hellclanner at live dot com
13 年前
請注意,如果您在 ob_start 和 ob_end_clean 或 ob_end_flush 之間更改 zlib 輸出壓縮設定,您將會收到錯誤:ob_end_flush() 無法刪除緩衝區 zlib 輸出壓縮

範例

<?php

ob_start
();

$output = ob_get_contents();

ini_set('zlib.output_compression', '1');

ob_end_clean();

?>

此範例中的 ob_end_clean(); 將會拋出錯誤。
John Smith
20 年前
請注意,如果您使用回呼函式呼叫 ob_start,即使您使用 ob_end_clean 捨棄輸出緩衝區,該回呼函式仍然會被呼叫。

因為一旦設定了回呼函式,就無法將其從輸出緩衝區中移除,阻止回呼函式產生任何作用的唯一方法是執行以下操作

<?php
$ignore_callback
= false;
ob_start('my_callback');
...
if(
$need_to_abort) {
$ignore_callback = true;
ob_end_clean();
...
}

function
my_callback(&$buffer) {
if(
$GLOBALS['ignore_callback']) {
return
"";
}
...
}
?>
baklanoid at gmail dot com
4 年前
如果對輸出緩衝沒有把握(已啟用或未啟用),
您可以嘗試這些防護措施

<?php

while (ob_get_level() !== 0) {
ob_end_clean();
}

// 或

while (ob_get_length() !== false) {
ob_end_clean();
}

?>
programmer at bardware dot de
21 年前
如果您希望在客戶端已經擁有最新版本時阻止腳本執行,您可以這樣做:
您可以這樣做:

ob_start();

$mtime=filemtime($_SERVER["SCRIPT_FILENAME"])-date("Z");
$gmt_mtime = date('D, d M Y H:i:s', $mtime) . ' GMT';

$headers = getallheaders();

if(isset($headers["If-Modified-Since"])) {
if ($headers["If-Modified-Since"] == $gmt_mtime) {
header("HTTP/1.1 304 Not Modified");
ob_end_clean();
exit;
}
}

$size=ob_get_length();
header("Last-Modified: ".$gmt_mtime);
header("Content-Length: $size");
ob_end_flush();

當然,您可以查詢資料庫或採用任何與腳本結果修改相關的日期,而不是將 If-Modified-Since 標頭與腳本上次修改日期進行比較。

例如,您可以使用此技術動態生成圖像。如果使用者透過 If-Modified-Since 標頭指示他已經擁有圖像的版本,則無需生成圖像,並讓伺服器最終將其捨棄,因為伺服器僅在之後才會解釋 If-Modified-Since 標頭。
這樣可以節省伺服器負載並縮短響應時間。
daijoubuNOSP at Mvideotron dot com
20 年前
關於先前的評論
您也可以依賴 ETag 並簡單地使用 time()

<?php
$time
= time();
$mins = 1;
if (isset(
$_SERVER['HTTP_IF_NONE_MATCH']) and str_replace('"', '', $_SERVER['HTTP_IF_NONE_MATCH'])+($mins*60) > $time)
{
header('HTTP/1.1 304 Not Modified');
exit();
}
else
{
header('ETag: "'.$time.'"');
}
echo
'快取 ', $mins*60, ' 秒<br/>', date('G:i:s');
?>
netom at elte dot hu
14 年前
請注意,ob_end_clean() 會捨棄標頭。

如果您想清除輸出緩衝區,但不清除標頭(例如,因為您使用 firephp...),那麼這就是解決方案

<?php
...

$headers = array();
if ( !
headers_sent() ) {
$headers = apache_response_headers();
}

ob_end_clean();
ob_start();

if ( !empty(
$headers ) ) {
foreach (
$headers as $name => $value ) {
header( "$name: $value" );
}
}

...
?>

我在網頁應用程式的通用例外處理器中使用它,它會清除緩衝區(但不清除包含除錯資訊的標頭),並使用 readfile() 傳送 500 錯誤頁面。

祝 PHP 使用愉快,

Tamas.
everling
18 年前
請記住,mrfritz379 的範例 (#49800) 只是一個範例。您可以用更有效率的方式達成該範例的結果,而無需使用輸出緩衝函式

echo "<p>搜尋執行中。請耐心等候。。。";
$output = "<p>檔案列表:</p>\n";
if (is_dir($dir)) {
$dh = opendir($dir);

while (($fd = readdir($dh)) != false) {
echo " .";
$output .= $fd;
}
}
echo "</br>搜尋完成!</p>\n";
echo $output;





除了 John Smith 的評論 (#42939) 之外,即使您呼叫 ob_end_clean(),ob_gzhandler() 仍可能會將 HTTP 標頭「Content-Encoding」設定為「gzip」或「deflate」。這會在以下情況下造成問題

1. 呼叫 ob_gzhandler()。
2. 顯示「一些內容」;
3. 呼叫 ob_end_clean()。
4. 顯示「新內容」;

在上述情況下,瀏覽器可能會收到「Content-Encoding: gzip」HTTP 標頭,並嘗試解壓縮未壓縮的「新內容」。瀏覽器將會失敗。

在以下情況下,此行為將不會被注意到

1. 呼叫 ob_gzhandler()。
2. 顯示「一些內容」;
3. 呼叫 ob_end_clean()。
4. 呼叫 ob_gzhandler()。
5. 顯示「新內容」;

這是因為第二個 ob_gzhandler() 將會掩蓋第一個 ob_gzhandler() 的缺失。

解決方案是像 John Smith 那樣為 ob_gzhandler() 編寫一個包裝器。
geoff at spacevs dot com
17 年前
如果您在以「register_shutdown_function」註冊的函式中呼叫 ob_end_clean,那就太遲了,任何緩衝區都已經發送到用戶端。
Adam of Fusion Bay
18 年前
您可能需要注意從回呼函式內呼叫 ob_end_clean()。我相信這會在 PHP 中產生無窮迴圈。
tyler @
16 年前
關於 <geoff at spacevs dot com> 所說的「如果您在以 'register_shutdown_function' 註冊的函式中呼叫 ob_end_clean,那就太遲了,任何緩衝區都已經發送到用戶端。」,以下是我想出的解決方法。

<?php

function ClearBuffer($Buffer) {
return
"";
}

function
Shutdown() {
ob_start("ClearBuffer");
}

register_shutdown_function("Shutdown");

?>

這會清除所有輸入到輸出緩衝區的內容。基本上它與 "STDOUT > /dev/null" 相同。
mrfritz379
19 年前
這可能在其他地方貼過,但我沒看過。
要在程式執行時顯示進度指示器,但不輸出輸出緩衝區的內容,可以使用以下方法:

echo "<p>搜尋執行中。請耐心等候。。。";
$output = "<p>檔案列表:</p>\n";
if (is_dir($dir)) {
$dh = opendir($dir);

while (($fd = readdir($dh)) != false) {
echo " .";
ob_start();
echo $fd;
$output .= ob_get_contents();
ob_end_clean();
}
}
echo "</br>搜尋完成!</p>\n";
echo $output;

程式將繼續印出「.」,而不印出檔案列表。然後會印出「搜尋完成」訊息,接著是緩衝的檔案列表。
To Top