<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/book.outcontrol.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'zh',
  ),
  'this' => 
  array (
    0 => 'outcontrol.user-level-output-buffers.php',
    1 => '用户级输出缓冲区',
    2 => '用户级输出缓冲区',
  ),
  'up' => 
  array (
    0 => 'book.outcontrol.php',
    1 => '输出控制',
  ),
  'prev' => 
  array (
    0 => 'outcontrol.flushing-system-buffers.php',
    1 => '冲刷系统缓冲区',
  ),
  'next' => 
  array (
    0 => 'outcontrol.what-output-is-buffered.php',
    1 => '什么输出会被缓冲？',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'zh',
    'path' => 'reference/outcontrol/user-level-output-buffers.xml',
  ),
  'history' => 
  array (
  ),
  'extra_header_links' => 
  array (
    'rel' => 'alternate',
    'href' => '/manual/en/feeds/outcontrol.user-level-output-buffers.atom',
    'type' => 'application/atom+xml',
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="outcontrol.user-level-output-buffers" class="chapter">
 <h1 class="title">用户级输出缓冲区</h1>
<h2>目录</h2><ul class="chunklist chunklist_chapter"><li><a href="outcontrol.what-output-is-buffered.php">什么输出会被缓冲？</a></li><li><a href="outcontrol.nesting-output-buffers.php">嵌套输出缓冲区</a></li><li><a href="outcontrol.buffer-size.php">缓冲区大小</a></li><li><a href="outcontrol.operations-on-buffers.php">缓冲区中允许的操作</a></li><li><a href="outcontrol.output-handlers.php">输出处理程序</a></li><li><a href="outcontrol.working-with-output-handlers.php">使用输出处理程序</a></li><li><a href="outcontrol.flags-passed-to-output-handlers.php">传递给输出处理程序的 flag</a></li><li><a href="outcontrol.output-handler-return-values.php">输出处理程序的返回值</a></li></ul>

 <p class="para">
  用户级输出缓冲区可以从 PHP 代码中启动、操作和终止。
  每个缓冲区都包括一个输出缓冲区和一个关联的输出处理程序函数。
 </p>

 

 <div class="section">
  <h2 class="title">打开输出缓冲</h2>
  <p class="para">
   可以通过使用 <span class="function"><a href="function.ob-start.php" class="function">ob_start()</a></span> 函数或设置 <a href="outcontrol.configuration.php#ini.output-buffering" class="link">output_buffering</a> 和
   <a href="outcontrol.configuration.php#ini.output-handler" class="link">output_handler</a> <var class="filename">php.ini</var> 配置来启用输出缓冲。虽然两者都可以创建输出缓冲区，但 <span class="function"><a href="function.ob-start.php" class="function">ob_start()</a></span>
   更加灵活，因为接受用户定义的函数作为输出处理程序，并且还可以设置对缓冲区允许的操作（冲刷、清空、移除）。通过 <span class="function"><a href="function.ob-start.php" class="function">ob_start()</a></span>
   开始的缓冲区将从调用该函数的行开始生效，而通过 <a href="outcontrol.configuration.php#ini.output-buffering" class="link">output_buffering</a> 开始的缓冲区将从脚本的第一行开始缓冲输出。
  </p>
  <p class="para">
   PHP 还自带了内置的 <code class="literal">&quot;URL-Rewriter&quot;</code> 输出处理程序，它会启动自己的输出缓冲区，并且任何时候最多只允许有两个实例运行（一个用于用户级别的
   URL 重写，另一个用于透明 Session ID 支持）。这些缓冲区可以通过调用 <span class="function"><a href="function.output-add-rewrite-var.php" class="function">output_add_rewrite_var()</a></span> 函数或启用
   <a href="session.configuration.php#ini.session.use-trans-sid" class="link">session.use_trans_sid</a> php.ini 设置来启动。
  </p>
  <p class="para">
   捆绑的 <code class="literal">zlib</code> 扩展有自己的输出缓冲区，可以使用
   <a href="zlib.configuration.php#ini.zlib.output-compression" class="link">zlib.output_compression</a>
   <var class="filename">php.ini</var> 设置启用。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    <code class="literal">&quot;URL-Rewriter&quot;</code> 的特殊之处在于同时只允许运行最多两个实例，但所有用户级输出缓冲区都使用 <span class="function"><a href="function.ob-start.php" class="function">ob_start()</a></span>
    所使用的相同底层缓冲区，并通过自定义的输出处理函数来实现其功能。因此，它们的所有功能都可以由用户级代码模拟。
   </span>
  </p></blockquote>
 </div>

 

 

 

 <div class="section">
  <h2 class="title">冲刷、访问和清理缓冲区内容</h2>
  <p class="para">
   冲刷会发送并丢弃活动缓冲区中的内容。当输出的大小超过缓冲区大小时，或者在脚本结束时，又或者是调用了
   <span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span> 或
   <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 函数时，会冲刷输出缓冲区。
  </p>
  <div class="caution"><strong class="caution">警告</strong>
   <p class="simpara">
    调用 <span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>
    或 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 将关闭活跃的缓冲区。
   </p>
  </div>
  <div class="caution"><strong class="caution">警告</strong>
   <p class="simpara">
    冲刷缓冲区将冲刷输出处理程序的返回值，这可能与缓冲区的内容不同。
    例如，使用 <span class="function"><a href="function.ob-gzhandler.php" class="function">ob_gzhandler()</a></span> 将压缩输出并冲刷压缩后的输出。
   </p>
  </div>
  <p class="para">
   可以通过调用 <span class="function"><a href="function.ob-get-contents.php" class="function">ob_get_contents()</a></span>、<span class="function"><a href="function.ob-get-clean.php" class="function">ob_get_clean()</a></span>
   或 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 来检索活动缓冲区的内容。
  </p>
  <p class="para">
   如果只需要缓冲区内容的长度，<span class="function"><a href="function.ob-get-length.php" class="function">ob_get_length()</a></span> 或
   <span class="function"><a href="function.ob-get-status.php" class="function">ob_get_status()</a></span> 将返回内容的字节长度。
  </p>
  <div class="caution"><strong class="caution">警告</strong>
   <p class="simpara">
    调用 <span class="function"><a href="function.ob-get-clean.php" class="function">ob_get_clean()</a></span>
    或 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 将在返回其内容后关闭活跃的缓冲区。
   </p>
  </div>
  <p class="para">
   可以通过调用 <span class="function"><a href="function.ob-clean.php" class="function">ob_clean()</a></span>、<span class="function"><a href="function.ob-end-clean.php" class="function">ob_end_clean()</a></span>
   或 <span class="function"><a href="function.ob-get-clean.php" class="function">ob_get_clean()</a></span> 来清理活动缓冲区的内容。
  </p>
  <div class="caution"><strong class="caution">警告</strong>
   <p class="simpara">
    调用 <span class="function"><a href="function.ob-end-clean.php" class="function">ob_end_clean()</a></span>
    或 <span class="function"><a href="function.ob-get-clean.php" class="function">ob_get_clean()</a></span> 将关闭活跃的缓冲区。
   </p>
  </div>
 </div>

 <div class="section">
  <h2 class="title">关闭缓冲区</h2>
  <p class="para">
   可以通过调用 <span class="function"><a href="function.ob-end-clean.php" class="function">ob_end_clean()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>、
   <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 或 <span class="function"><a href="function.ob-get-clean.php" class="function">ob_get_clean()</a></span> 来关闭输出缓冲区。
  </p>
  <div class="warning"><strong class="warning">警告</strong>
   <p class="simpara">
    没有使用 <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-removable">PHP_OUTPUT_HANDLER_REMOVABLE</a></code></strong> 标志启动的输出缓冲区不能关闭，可能会生成一个
    <strong><code><a href="errorfunc.constants.php#constant.e-notice">E_NOTICE</a></code></strong>。
   </p>
  </div>
  <p class="para">
   脚本结束时或调用 <span class="function"><a href="function.exit.php" class="function">exit()</a></span> 时，所有未关闭的输出缓冲区都将被冲刷并关闭。
   缓冲区将按照它们启动的相反顺序被冲刷并关闭。
   最后启动的缓冲区将首先被冲刷，最先启动的缓冲区将最后被冲刷并关闭。
  </p>
  <div class="caution"><strong class="caution">警告</strong>
   <p class="simpara">
    如果不希望冲刷缓冲区的内容，应该使用自定义的输出处理程序来防止在关闭期间冲刷缓冲区的内容。
   </p>
  </div>
 </div>

 

 

 

 

 <div class="section">
  <h2 class="title">输出处理程序中抛出异常</h2>
  <p class="para">
   如果在输出处理程序中抛出未捕获的异常，则程序将终止，并在关闭过程中调用处理程序后刷新
   <code class="literal">&quot;Uncaught Exception&quot;</code> 错误消息。
  </p>
  <p class="para">
   如果未捕获的异常是在由 <span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>
   或 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 调用的处理程序中引发的，
   则在错误消息之前刷新缓冲区的内容。
  </p>
  <p class="para">
   如果在关闭过程中的输出处理程序中引发未捕获的异常，则程序终止，而不刷新缓冲区或错误消息。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    如果处理程序抛出异常，则设置其
    <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-disabled">PHP_OUTPUT_HANDLER_DISABLED</a></code></strong> 状态标志。
   </span>
  </p></blockquote>
 </div>

 <div class="section">
  <h2 class="title">输出处理程序中引发错误</h2>
  <p class="para">
   如果在输出处理程序中引发非致命错误，则程序继续执行。
  </p>
  <p class="para">
   如果非致命错误是在由 <span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>
   或 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 调用的处理程序中引发的，
   则根据处理程序的返回值刷新特定的数据。
   如果处理程序返回 <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong> 则刷新缓冲区和错误消息。
   如果返回其他任何值，则刷新处理程序的返回值，但不刷新错误消息。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    如果处理程序返回 <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>，则设置其
    <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-disabled">PHP_OUTPUT_HANDLER_DISABLED</a></code></strong> 状态标志。
   </span>
  </p></blockquote>
  <p class="para">
   如果输出处理程序中出现致命错误，则程序终止，并在关闭过程中调用处理程序后刷新错误消息。
  </p>
  <p class="para">
   如果致命错误是在由 <span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>
   或 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 调用的处理程序中引发的，
   则在错误消息之前刷新缓冲区的内容。
  </p>
  <p class="para">
   如果在关闭过程中的输出处理程序中引发致命错误，则程序终止，而不刷新缓冲区或错误消息。
  </p>
 </div>

 <div class="section">
  <h2 class="title">输出处理程序中输出</h2>
  <p class="para">
   在特定情况下，处理程序中生成的输出与缓冲区的内容一起刷新。
   此输出不会附加到缓冲区，也不是由 <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 返回的字符串的一部分。
  </p>
  <p class="para">
   在冲刷操作（调用 <span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>、
   <span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span> 和关闭过程中）期间，
   如果处理程序的返回值为 <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>，则缓冲区的内容将被刷新，然后输出。
   如果处理程序在关闭过程中被调用，则抛出异常或调用 <span class="function"><a href="function.exit.php" class="function">exit()</a></span> 会导致相同的行为。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    如果处理程序返回 <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>，则设置其
    <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-disabled">PHP_OUTPUT_HANDLER_DISABLED</a></code></strong> 状态标志。
   </span>
  </p></blockquote>
 </div>

 <div class="section">
  <h2 class="title">输出处理程序状态 flag</h2>
  <p class="para">
   每次调用输出处理程序时，缓冲区的 <code class="literal">flags</code> 位掩码的
   <a href="outcontrol.constants.php#outcontrol.constants.flags-returned-by-handler" class="link">处理程序状态标志</a>
   都会被设置，并且是由 <span class="function"><a href="function.ob-get-status.php" class="function">ob_get_status()</a></span> 返回的
   <code class="literal">flags</code> 的一部分。
   如果处理程序成功执行且未返回 <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>，则设置
   <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-started">PHP_OUTPUT_HANDLER_STARTED</a></code></strong> 和
   <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-processed">PHP_OUTPUT_HANDLER_PROCESSED</a></code></strong>。
   如果处理程序在执行时返回 <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong> 或引发异常，则设置
   <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-started">PHP_OUTPUT_HANDLER_STARTED</a></code></strong> 和
   <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-disabled">PHP_OUTPUT_HANDLER_DISABLED</a></code></strong>。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    如果处理程序设置了 <strong><code><a href="outcontrol.constants.php#constant.php-output-handler-disabled">PHP_OUTPUT_HANDLER_DISABLED</a></code></strong> 标志，
    则不会调用 <span class="function"><a href="function.ob-end-clean.php" class="function">ob_end_clean()</a></span>、<span class="function"><a href="function.ob-end-flush.php" class="function">ob_end_flush()</a></span>、
    <span class="function"><a href="function.ob-get-clean.php" class="function">ob_get_clean()</a></span>、<span class="function"><a href="function.ob-get-flush.php" class="function">ob_get_flush()</a></span>、
    <span class="function"><a href="function.ob-clean.php" class="function">ob_clean()</a></span>、<span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span>
    或 PHP 的关闭过程。
    在 PHP 8.4.0 之前，调用 <span class="function"><a href="function.ob-clean.php" class="function">ob_clean()</a></span> 或 <span class="function"><a href="function.ob-flush.php" class="function">ob_flush()</a></span> 时，此标志不起作用。
   </span>
  </p></blockquote>
 </div>

</div>
<?php manual_footer($setup); ?>