mirror of
https://github.com/php/doc-en.git
synced 2026-03-23 23:32:18 +01:00
125 lines
5.5 KiB
XML
125 lines
5.5 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<chapter xml:id="opcache.preloading" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Preloading</title>
|
|
|
|
<para>
|
|
As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache when the engine
|
|
starts. Any functions, classes, interfaces, or traits (but not constants) in those files will then become
|
|
globally available for all requests without needing to be explicitly included. That trades
|
|
convenience and performance (because the code is always available) for baseline memory usage. It also
|
|
requires restarting the PHP process to clear pre-loaded scripts, meaning this feature is
|
|
only practical to use in production, not in a development environment.
|
|
</para>
|
|
|
|
<para>
|
|
Note that the optimal tradeoff between performance and memory may vary with the application.
|
|
"Preload everything" may be the easiest strategy, but not necessarily the best strategy. Additionally,
|
|
preloading is only useful when there is a persistent process from one request to another. That means
|
|
while it can work in a CLI script if the opcache is enabled, it's generally pointless. The exception
|
|
is when using preloading on <link linkend="ffi.examples-complete">FFI libraries</link>.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
Preloading is not supported on Windows.
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
Configuring preloading involves two steps, and requires that the opcache be enabled.
|
|
First, set the <link linkend="ini.opcache.preload">opcache.preload</link>
|
|
value in &php.ini;:
|
|
</para>
|
|
|
|
<informalexample>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
opcache.preload=preload.php
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
|
|
<para>
|
|
<filename>preload.php</filename> is an arbitrary file that will run once at server startup
|
|
(PHP-FPM, mod_php, etc.) and load code into persistent memory. In servers that startup as
|
|
root before switching to an unprivileged system user, or if PHP will be run as root
|
|
(not recommended), the <link linkend="ini.opcache.preload-user">opcache.preload_user</link>
|
|
value can specify the system user to run the preloading. Running preloading as root is not allowed
|
|
by default. Set <literal>opcache.preload_user=root</literal> to explicitly allow it.
|
|
</para>
|
|
|
|
<para>
|
|
In the <filename>preload.php</filename> script, any file referenced by <function>include</function>,
|
|
<function>include_once</function>, <function>require</function>, <function>require_once</function>, or
|
|
<function>opcache_compile_file</function> will be parsed into persistent memory. In the following example,
|
|
all <filename>.php</filename> files in the <filename>src</filename> directory will be preloaded, unless they
|
|
are a <literal>Test</literal> file.
|
|
</para>
|
|
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$directory = new RecursiveDirectoryIterator(__DIR__ . '/src');
|
|
$fullTree = new RecursiveIteratorIterator($directory);
|
|
$phpFiles = new RegexIterator($fullTree, '/.+((?<!Test)+\.php$)/i', RecursiveRegexIterator::GET_MATCH);
|
|
|
|
foreach ($phpFiles as $key => $file) {
|
|
require_once($file[0]);
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
|
|
<para>
|
|
Both <function>include</function> and <function>opcache_compile_file</function> will work, but have different
|
|
implications for how code gets handled.
|
|
|
|
<itemizedlist>
|
|
<listitem><simpara><function>include</function> will execute code in the file,
|
|
while <function>opcache_compile_file</function> will not. That means only the former supports
|
|
conditional declaration (functions declared inside an if-block).</simpara></listitem>
|
|
<listitem><simpara>Because <function>include</function> will execute code, nested <function>include</function>d
|
|
files will also be parsed and their declarations preloaded.</simpara></listitem>
|
|
<listitem><simpara><function>opcache_compile_file</function> can load files in any order. That is, if
|
|
<filename>a.php</filename> defines class <literal>A</literal> and <filename>b.php</filename> defines class
|
|
<literal>B</literal> that extends <literal>A</literal>, then <function>opcache_compile_file</function> can
|
|
load those two files in any order. When using <function>include</function>, however, <filename>a.php</filename>
|
|
<emphasis>must</emphasis> be included first.</simpara></listitem>
|
|
<listitem><simpara>In either case, if a later script includes a file that has already been preloaded then
|
|
its contents will still execute, but any symbols it defines will not be re-defined. Using
|
|
<function>include_once</function> will not prevent the file from being included a second time. It
|
|
may be necessary to load a file again in order to include global constants defined in it, as those are not
|
|
handled by preloading.</simpara></listitem>
|
|
</itemizedlist>
|
|
|
|
Which approach is better therefore depends on the desired behavior. With code that would otherwise use an
|
|
autoloader, <function>opcache_compile_file</function> allows for greater flexibility. With code that would
|
|
otherwise be loaded manually, <function>include</function> will be more robust.
|
|
</para>
|
|
|
|
</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
|
|
-->
|