This is an old revision of the document!
PHP RFC: Continue output buffering despite aborted connection
- Version: 1.0
- Date: 2015-02-19
- Last-Modfied: 2015-02-19
- Author: Michael Wallner mike@php.net
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/continue_ob
Introduction
The output buffering technique is used to speed up output, but also to capture intermediate output and use it elsewhere.
Often, particularly with functions which directly generate output, this is the only way to accumulate that data.
Current Status
As of PHP-5.4
ignore_user_abort = FALSE
The script ends as soon as an aborted connection is detected, either by an unbuffered write or an output exceeding it's chunk size (which would result in an unbuffered write).
ignore_user_abort = TRUE
The script continues to run, but any already buffered output will be discarded after processing by any output handler, and more importantly, any output generated by the script is simply discarded, without ever hitting the output buffer or any output handler. Output buffers and handlers will just sit in the stack until the output layer is deactivated.
Proposal
Let the output buffering functions stay usable after the connection was already aborted.
This will be effective only for scripts that do set ignore_user_abort, i.e. script execution will end when an aborted connection was detected and ignore_user_abort was not set, just as it used to.
ignore_user_abort = FALSE
Nothing changes.
ignore_user_abort = TRUE
The output buffer stack stays intact and usable. Any generated output will be passed to any output buffers, which will call any output handlers to process the buffer. Only now will any generated output of the output handler be discarded.
Bacon^WBenefits
Usage of ob_start([callback]) behaves the same, whether the connection was aborted or not. Still, you have to deliberately enable it with ignore_user_abort(TRUE).
Backward Incompatible Changes
Output handlers will be called when ignore_user_abort is TRUE.
Proposed PHP Version(s)
PHP 7.0
Unaffected PHP Functionality
Standard behavior will stay the same.
Proposed Voting Choices
Simple YES/NO vote with a 50%+1 majority needed to accept this RFC.
Implementation
diff --git a/main/output.c b/main/output.c index 22ac26a..a0a300b 100644 --- a/main/output.c +++ b/main/output.c @@ -242,9 +242,6 @@ PHPAPI int php_output_get_status(void) * Unbuffered write */ PHPAPI size_t php_output_write_unbuffered(const char *str, size_t len) { - if (OG(flags) & PHP_OUTPUT_DISABLED) { - return 0; - } if (OG(flags) & PHP_OUTPUT_ACTIVATED) { return sapi_module.ub_write(str, len); } @@ -256,13 +253,13 @@ PHPAPI size_t php_output_write_unbuffered(const char *str, size_t len) * Buffered write */ PHPAPI size_t php_output_write(const char *str, size_t len) { - if (OG(flags) & PHP_OUTPUT_DISABLED) { - return 0; - } if (OG(flags) & PHP_OUTPUT_ACTIVATED) { php_output_op(PHP_OUTPUT_HANDLER_WRITE, str, len); return len; } + if (OG(flags) & PHP_OUTPUT_DISABLED) { + return 0; + } return php_output_direct(str, len); } /* }}} */
References
A bug about the current behavior:
https://bugs.php.net/bug.php?id=67381
A bug about apparent pre-5.4 behavior:
https://bugs.php.net/bug.php?id=64152
Changelog
- 1.0 Proposed