用户级输出缓冲区

目录

用户级输出缓冲区可以在 PHP 代码中启动、操作和终止。每个缓冲区包含一个输出缓冲区和一个关联的输出处理程序函数。

开启输出缓冲

可以使用 ob_start() 函数或设置 output_bufferingoutput_handler php.ini 设置来开启输出缓冲。虽然两者都可以创建输出缓冲区,但 ob_start() 更加灵活,因为它接受用户定义的函数作为输出处理程序,并且还可以设置允许对缓冲区进行的操作(刷新、清除、删除)。使用 ob_start() 启动的缓冲区将在调用该函数的行开始生效,而使用 output_buffering 启动的缓冲区将从脚本的第一行开始缓冲输出。

PHP 还附带一个内置的 "URL-Rewriter" 输出处理程序,它启动自己的输出缓冲区,并且在任何时候只允许最多两个实例运行(一个用于用户级 URL 重写,一个用于透明的会话 ID 支持)。可以通过调用 output_add_rewrite_var() 函数和/或启用 session.use_trans_sid php.ini 设置来启动这些缓冲区。

捆绑的 zlib 扩展有自己的输出缓冲区,可以通过使用 zlib.output_compression php.ini 设置启用。

注意: 虽然 "URL-Rewriter" 的特殊之处在于它在任何时候只允许最多两个实例运行,但所有用户级输出缓冲区都使用与 ob_start() 使用的相同底层缓冲区,其功能由自定义输出处理程序函数实现。因此,所有这些功能都可以通过用户级代码模拟。

刷新、访问和清除缓冲区内容

刷新会发送并丢弃活动缓冲区的内容。当输出大小超过缓冲区大小时,脚本结束或调用 ob_flush()ob_end_flush()ob_get_flush() 时,输出缓冲区会被刷新。

注意

调用 ob_end_flush()ob_get_flush() 将关闭活动缓冲区。

注意

刷新缓冲区将刷新输出处理程序的返回值,这可能与缓冲区的内容不同。例如,使用 ob_gzhandler() 将压缩输出并刷新压缩后的输出。

可以通过调用 ob_get_contents()ob_get_clean()ob_get_flush() 来检索活动缓冲区的内容。

如果只需要缓冲区内容的长度,ob_get_length()ob_get_status() 将返回内容的字节长度。

注意

调用 ob_get_clean()ob_get_flush() 将在返回其内容后关闭活动缓冲区。

可以通过调用 ob_clean()ob_end_clean()ob_get_clean() 来清除活动缓冲区的内容。

注意

调用 ob_end_clean()ob_get_clean() 将关闭活动缓冲区。

关闭缓冲区

可以通过调用 ob_end_clean()ob_end_flush()ob_get_flush()ob_get_clean() 来关闭输出缓冲区。

警告

没有使用 PHP_OUTPUT_HANDLER_REMOVABLE 标志启动的输出缓冲区无法关闭,可能会生成 E_NOTICE 错误。

每个在脚本结束时或调用 exit() 时未关闭的输出缓冲区都将被 PHP 的关闭进程刷新并关闭。缓冲区将按启动顺序的相反顺序刷新和关闭。最后启动的缓冲区将首先被刷新,第一个启动的缓冲区将最后被刷新和关闭。

注意

如果不需要刷新缓冲区内容,则应使用自定义输出处理程序以防止在关闭期间刷新。

在输出处理程序中抛出的异常

如果在输出处理程序中抛出未捕获的异常,程序将终止,并且处理程序将在关闭进程后被调用,之后将刷新 "Uncaught Exception" 错误消息。

如果未捕获的异常是在 ob_flush()ob_end_flush()ob_get_flush() 调用的处理程序中抛出的,则在错误消息之前会刷新缓冲区内容。

如果在关闭期间输出处理程序中抛出未捕获的异常,则处理程序将被终止,并且不会刷新缓冲区内容或错误消息。

注意: 如果处理程序抛出异常,则会设置其 PHP_OUTPUT_HANDLER_DISABLED 状态标志。

在输出处理程序中引发的错误

如果在输出处理程序中引发非致命错误,程序将继续执行。

如果非致命错误是在 ob_flush()ob_end_flush()ob_get_flush() 调用的处理程序中引发的,则缓冲区会根据处理程序的返回值刷新某些数据。如果处理程序返回 false,则缓冲区和错误消息将被刷新。如果返回任何其他内容,则处理程序返回值将被刷新,但错误消息不会被刷新。

注意: 如果处理程序返回 false,则会设置其 PHP_OUTPUT_HANDLER_DISABLED 状态标志。

如果在输出处理程序中引发致命错误,则程序将终止,并且处理程序将在关闭进程后被调用,之后将刷新错误消息。

如果致命错误是在 ob_flush()ob_end_flush()ob_get_flush() 调用的处理程序中引发的,则在错误消息之前会刷新缓冲区内容。

如果在关闭期间输出处理程序中引发致命错误,则程序将终止,而不会刷新缓冲区或错误消息。

输出处理程序中的输出

在某些情况下,处理程序中产生的输出将与缓冲区内容一起刷新。此输出不会追加到缓冲区,也不属于 ob_get_flush() 返回的字符串的一部分。

在刷新操作期间(调用 ob_flush()ob_end_flush()ob_get_flush() 以及在关闭期间),如果处理程序的返回值为 false,则缓冲区内容将被刷新,然后是输出。如果处理程序没有在关闭期间被调用,则处理程序抛出异常或调用 exit() 会导致相同的结果。

注意: 如果处理程序返回 false,则会设置其 PHP_OUTPUT_HANDLER_DISABLED 状态标志。

输出处理程序状态标志

缓冲区的flags 位掩码的 处理程序状态标志 在每次调用输出处理程序时都会被设置,并且是ob_get_status()返回的flags的一部分。如果处理程序成功执行并且不返回false,则会设置PHP_OUTPUT_HANDLER_STARTEDPHP_OUTPUT_HANDLER_PROCESSED。如果处理程序返回false 或在执行时抛出异常,则会设置PHP_OUTPUT_HANDLER_STARTEDPHP_OUTPUT_HANDLER_DISABLED

注意: 如果处理程序的PHP_OUTPUT_HANDLER_DISABLED 设置,则通过调用ob_end_clean()ob_end_flush()ob_get_clean()ob_get_flush() 或在 PHP 的关闭过程中,不会调用该处理程序。此标志对调用ob_clean()ob_flush() 无效。

添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top