-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathpreload.xml
More file actions
156 lines (141 loc) · 9.06 KB
/
preload.xml
File metadata and controls
156 lines (141 loc) · 9.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 87d6bb1bbd5f118f5b0cf0160438f06c0f91ea45 Maintainer: rjhdby Status: ready -->
<!-- Reviewed: no -->
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="opcache.preloading">
<title>Предзагрузка</title>
<simpara>
Начиная с PHP 7.4.0 разрешили настройку PHP на предварительную загрузку скриптов
в память модуля opcache при запуске движка. Доступ к функциям, классам, интерфейсам
или трейтам (но не константам) в этих файлах станет глобальным для всех запросов;
файлы не потребуется включать явно. Предзагрузка повышает удобство
и производительность за счёт постоянной доступности кода для очередных запросов,
но увеличивает расход памяти. Одновременно с этим, изменения в предзагруженных скриптах
вступят в силу только после перезагрузки PHP-процесса, которая очистит скрипты,
которые предварительно загрузили. Поэтому предзагрузку скриптов выполняют
только в производственном окружении, а не в среде разработки.
</simpara>
<simpara>
Баланс между ростом производительности и расходом памяти зависит от приложения.
«Предзагрузка каждого файла» выглядит как простейшая стратегия, но такая стратегия полезна не в каждом сценарии.
Предзагрузка полезна, только когда процесс не изменяется от запроса к запросу.
Поэтому, хотя предзагрузка и работает в CLI-скрипте при включённом модуле opcache,
это бесполезно. Исключение — предварительная загрузка
<link linkend="ffi.examples-complete">библиотек FFI</link>.
</simpara>
<note>
<simpara>
ОС Windows не поддерживает предзагрузку.
</simpara>
</note>
<simpara>
Настройка предзагрузки состоит из двух этапов и работает, только если включили модуль opcache.
Сначала устанавливают значение для директивы <link linkend="ini.opcache.preload">opcache.preload</link>
в файле &php.ini;:
</simpara>
<informalexample>
<programlisting role="ini">
<![CDATA[
opcache.preload=preload.php
]]>
</programlisting>
</informalexample>
<simpara>
Файл <filename>preload.php</filename> — произвольный файл, который запустится один раз при старте сервера
в режиме менеджера процессов PHP-FPM, Apache-модуля mod_php и т. д. и загрузит код в постоянную память.
На серверах, которые перед переключением на непривилегированного пользователя системы запускаются
от имени root-пользователя, или если PHP запускается от имени root, что делать не рекомендуют,
пользователя системы для запуска предварительной загрузки указывают в директиве
<link linkend="ini.opcache.preload-user">opcache.preload_user</link>.
Запуск предварительной загрузки от имени root по умолчанию запрещён.
В файле конфигурации PHP устанавливают значение <literal>opcache.preload_user=root</literal>,
чтобы явно разрешить такой запуск.
</simpara>
<simpara>
PHP проанализирует и загрузит в постоянную память каждый файл,
который указали в выражениях <function>include</function>, <function>include_once</function>,
<function>require</function>, <function>require_once</function>
или в аргументе функции <function>opcache_compile_file</function> в скрипте <filename>preload.php</filename>.
В следующем примере загрузится каждый файл с расширением <filename class="extension">.php</filename>
в директории <filename>src</filename>,
если файл не содержат в названии части <literal>Test</literal>.
</simpara>
<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>
И выражение <function>include</function>, и функция <function>opcache_compile_file</function>
будут работать, но по-разному влияют на обработку кода.
<itemizedlist>
<listitem>
<simpara>
Выражение <function>include</function> выполнит код в файле,
а функция <function>opcache_compile_file</function> — нет,
поэтому только выражение включения файлов поддерживает условное объявление,
при котором функции объявляют в блоках if.
</simpara>
</listitem>
<listitem>
<simpara>
Поскольку выражение <function>include</function> выполняет код,
PHP также разберёт и предзагрузит объявления вложенных файлов,
которые включили выражением <function>include</function>.
</simpara>
</listitem>
<listitem>
<simpara>
Функция <function>opcache_compile_file</function> загружает файлы в произвольном порядке.
Даже если в файле <filename>a.php</filename> определили класс <literal>A</literal>,
а в файле <filename>b.php</filename> класс <literal>B</literal>,
который наследует класс <literal>A</literal>, это не изменит порядок загрузки файлов
и функция <function>opcache_compile_file</function> всё равно загрузит файлы в случайном порядке.
А выражение <function>include</function> первым <emphasis>обязательно</emphasis>
загрузит файл <filename>a.php</filename>.
</simpara>
</listitem>
<listitem>
<simpara>
В любом случае, если более поздний скрипт включает файл, который загрузился прежде,
то PHP всё равно выполнит содержимое файла, но не переопределит символы, которые в нём определили.
Выражение <function>include_once</function> не предотвратит повторное
включение файла. Иногда требуется загрузить файл снова, чтобы включить глобальные константы,
которые определили в файле, поскольку они не обрабатываются предварительной загрузкой.
</simpara>
</listitem>
</itemizedlist>
Поведение, которое ждут от кода, определяет, какой подход лучше. Для кода, который
иначе использовал бы автозагрузчик, функция <function>opcache_compile_file</function>
даёт больше гибкости. С кодом, который иначе загружался бы вручную,
часто надёжнее выражение <function>include</function>.
</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
-->