Skip to content

Commit

Permalink
[status working] Document details of output buffering / output control
Browse files Browse the repository at this point in the history
  • Loading branch information
mumumu committed Jan 27, 2024
1 parent 476ceee commit f43a224
Show file tree
Hide file tree
Showing 4 changed files with 913 additions and 1 deletion.
5 changes: 4 additions & 1 deletion reference/outcontrol/book.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 95bdd6883b5dde9504701777ba81b3c5f15df52b Maintainer: takagi Status: ready -->
<!-- EN-Revision: 7610e990293c87168d026ad078d8272e643e2c23 Maintainer: takagi Status: ready -->
<!-- CREDITS: shimooka,hirokawa -->

<book xml:id="book.outcontrol" xmlns="http://docbook.org/ns/docbook">
Expand All @@ -23,6 +23,9 @@

&reference.outcontrol.setup;
&reference.outcontrol.constants;
&reference.outcontrol.output-buffering;
&reference.outcontrol.flushing-system-buffers;
&reference.outcontrol.user-level-output-buffers;
&reference.outcontrol.examples;
&reference.outcontrol.reference;

Expand Down
158 changes: 158 additions & 0 deletions reference/outcontrol/flushing-system-buffers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 7610e990293c87168d026ad078d8272e643e2c23 Maintainer: mumumu Status: working -->
<chapter xml:id="outcontrol.flushing-system-buffers" xmlns="http://docbook.org/ns/docbook">
<section>
<title>Flushing System Buffers</title>
<para>
PHP provides two related ways
to flush (send and discard the contents of) system buffers:
through calling <function>flush</function>
and through enabling implicit flushing
with <function>ob_implicit_flush</function>
or the <link linkend="ini.implicit-flush">implicit_flush</link>
&php.ini; setting.
</para>
<para>
With implicit flushing disabled, PHP will flush output only
when <function>flush</function> is called or when the script ends.
</para>
<para>
With implicit flushing enabled, PHP will attempt to flush
after every block of code resulting in output.
Output in this context is non-zero length data that is:
<itemizedlist xml:id="outputcontrol.what-is-output">
<listitem>
<simpara>
outside of the <literal>&#60;?php ?&#62;</literal> tags
</simpara>
</listitem>
<listitem>
<simpara>
printed by language constructs and functions
whose explicit purpose is to output user provided variables or strings such as
<function>echo</function>, <function>print</function>,
<function>printf</function>, <function>var_dump</function>,
<function>var_export</function>, <function>vprintf</function>
</simpara>
</listitem>
<listitem>
<simpara>
printed by functions whose purpose is to collect and output
data/information on the running script or PHP such as
<function>debug_print_backtrace</function>, <function>phpcredits</function>,
<function>phpinfo</function>,
<methodname>ReflectionExtension::info</methodname>
</simpara>
</listitem>
<listitem>
<simpara>
printed by PHP on an uncaught exception or an unhandled error
(subject to the settings of
<link linkend="ini.display-errors">display_errors</link>
and <link linkend="ini.error-reporting">error_reporting</link>)
</simpara>
</listitem>
<listitem>
<simpara>
anything written to <literal>php://output</literal>
</simpara>
</listitem>
</itemizedlist>
</para>
<note>
<simpara>
Printing empty strings or sending headers is not considered output
and will not result in a flush operation.
</simpara>
</note>
<warning>
<simpara>
If implicit flushing is enabled, control characters
(e.g. <literal>"\n"</literal>, <literal>"\r"</literal>,
<literal>"\0"</literal>)
will trigger flushing as well.
</simpara>
</warning>
</section>

<section>
<title>Limitations</title>
<para>
This functionality cannot flush user-level output buffers.
To use these together, user-level output buffers must be flushed
before flushing system buffers in order for PHP to produce any output.
</para>
<warning>
<simpara>
Calling <function>flush</function> or implicit flushing being enabled
can interfere with output handlers of user-level output buffers
that set and send headers in a web context
(e.g. <function>ob_gzhandler</function>)
by sending headers before these handlers can do so.
</simpara>
</warning>
<para>
Buffering implemented by the underlying software/hardware
cannot be overridden by PHP and should be taken into account
when working with PHP's buffer control functions.
Checking the web servers/browsers/consoles buffering settings
and working with these can alleviate possible issues.
Working in a web context, either the web server's buffering settings
or the script's buffering could be adjusted to work in tandem
whereas working around the buffering strategies of various browsers
can be achieved by adjusting buffering in the PHP script.
On consoles that implement line buffering,
newline characters could be inserted in the appropriate places
before flushing output.
</para>
</section>

<section>
<title><acronym>SAPI</acronym> Differences In Flushing</title>
<para>
Although flushing is implemented by each <acronym>SAPI</acronym>
in a slightly different way,
these implementations fall in one of two categories:
<itemizedlist>
<listitem>
<simpara>
<acronym>SAPI</acronym>s used in a web context will flush headers first
followed by the output.
<literal>Apache2Handler</literal>, <literal>CGI</literal>,
<literal>FastCGI</literal> and <literal>FPM</literal>
are such <acronym>SAPI</acronym>s
</simpara>
</listitem>
<listitem>
<simpara>
other <acronym>SAPI</acronym>s
such as <literal>CLI</literal> and <literal>embed</literal>
will flush output only
</simpara>
</listitem>
</itemizedlist>
</para>
</section>

</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
117 changes: 117 additions & 0 deletions reference/outcontrol/output-buffering.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 7610e990293c87168d026ad078d8272e643e2c23 Maintainer: mumumu Status: working -->
<chapter xml:id="outcontrol.output-buffering" xmlns="http://docbook.org/ns/docbook">
<section>
<title>Output Buffering</title>
<para>
Output buffering is the buffering (temporary storage) of output
before it is flushed (sent and discarded) to the browser (in a web context)
or to the shell (on the command line).
While output buffering is active no output is sent from the script,
instead the output is stored in an internal buffer.
</para>
</section>

<section>
<title>Buffering Affecting PHP</title>
<para>
PHP relies on the underlying software/hardware infrastructure
when flushing output.
Buffering implemented by consoles on the command line (e.g. line buffered)
or web servers and browser in a web context (e.g. fully buffered)
do affect when output is displayed to the end-user.
Some of these effects can be eliminated by fine-tuning server settings
and/or aligning buffer sizes of the various layers.
</para>
</section>

<section>
<title>Output Buffering Control In PHP</title>
<para>
PHP provides a fully buffered user-level output buffer
with functions to start, manipulate and turn off the buffer
(most <link linkend="ref.outcontrol">ob_<replaceable>*</replaceable></link> functions),
and two functions to flush the underlying system buffers
(<function>flush</function> and <function>ob_implicit_flush</function>).
Some of this functionality can be set and/or configured
using the appropriate &php.ini; settings as well.
</para>
</section>

<section>
<title>Use Cases</title>
<para>
Output buffering is generally useful in situations when the buffered output
is modified or inspected, or it is used more than once in a request;
or when the controlled flushing of output is desired.
Specific use cases include:
<itemizedlist>
<listitem>
<simpara>
caching the result of compute/time intensive scripts
for example by generating static <literal>HTML</literal> pages
</simpara>
</listitem>
<listitem>
<simpara>
re-using the generated output by displaying it, saving it to a file
and/or sending it by email
</simpara>
</listitem>
<listitem>
<simpara>
flushing the <literal>head</literal> of an <literal>HTML</literal> page
separate from the <literal>body</literal> allows browsers
to load external resources while the script executes
potentially more time consuming processes
(e.g. database/file access, external network connection).
This is only useful if the <literal>HTTP</literal> status code
cannot change after the headers are sent
</simpara>
</listitem>
<listitem>
<simpara>
extracting information from functions that would otherwise produce output
(e.g. <function>phpinfo</function>)
</simpara>
</listitem>
<listitem>
<simpara>
controlling the output of third-party code by modifying/using parts
(e.g. extracting data, replacing words/phrases,
adding missing <literal>HTML</literal> tags),
or discarding it entirely under certain conditions (e.g. errors)
</simpara>
</listitem>
<listitem>
<simpara>
polyfilling certain unavailable web server functionality
(e.g. compressing or encoding output)
</simpara>
</listitem>
</itemizedlist>
</para>
</section>

</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Loading

0 comments on commit f43a224

Please sign in to comment.