Output Buffering and
ignore_user_abort()
Output buffering is a quite interesting feature in PHP, and when it was introduced in PHP 4, it took the PHP core developers quite a while to get right. In fact, some problems with output buffering were present even in PHP 5. The main use case for output buffering are templating engines. Traditionally, PHP code was directly embedded into HTML. Over time, more and more web applications moved away from using multiple scripts (pages) as entry points, and became so-called tunneling applications that would process every request through one front controller. This helps to eliminate redundant code and security issues are less likely, because all requests are processed by the same code, rather than leaving the possibility of neglecting the access rights checks on some pages.
With output buffering, PHP code can still be embedded into HTML pages, but rather than sending the boilerplate HTML together with the output generated by PHP directly back to the browser, the output can be captured and assigned to a variable. This allows for further processing, without the need to embed all code directly into the HTML page.
Another interesting feature in PHP – also with a lot of potential
for abuse – is the function ignore_user_abort()
and the
corresponding php.ini
setting
ignore_user_abort
. When a client (usually a browser)
sends an HTTP request to a server running PHP, a PHP program will be
executed on the server to process the request and return content
(usually a HTML page) in the form of an HTTP response. While the PHP
script runs on the server, however, the client might abort the
connection. In fact, a few years ago, most browsers still had stop
buttons.
From PHP’s viewpoint, it makes perfect sense to not just quit the execution of a script, but make sure that things are left in a consistent state by running through the script, and then saving the application state, for example as part of the session data. To achieve this, user aborts should be ignored.
In PHP 5.4, a bug was introduced that affected output buffering in combination with user aborts. When output buffering was enabled, and the user, or to be more precise, the client, aborted the request, the buffer was discarded. Since the user did not get to see the response anyway (after all, they had just aborted the request by terminating the HTTP connection), this bug went unnoticed for quite some time. But scripts trying to save the output buffer contents, maybe as part of a caching mechanism, would expose undesired behavior.
In PHP 7, this problem has been fixed. You should now be able to use output buffering even when requests are aborted.