Preloading
A partir do PHP 7.4.0, o PHP pode ser configurado para pré-carregar scripts no opcache quando o mecanismo é iniciado. Quaisquer funções, classes, interfaces ou traits (mas não constantes) nestes arquivos ficarão globalmente disponíveis para todas as solicitações sem precisar ser incluídas explicitamente. Isso troca conveniência e desempenho (porque o código está sempre disponível) para uso de memória de linha de base. Também requer a reinicialização do processo PHP para limpar os scripts pré-carregados, o que significa que esse recurso é prático apenas para uso em produção, não em um ambiente de desenvolvimento.
Observe que a compensação ideal entre desempenho e memória pode variar de acordo com o aplicativo. "Pré-carregar tudo" pode ser a estratégia mais fácil, mas não necessariamente a melhor estratégia. Além disso, o pré-carregamento só é útil quando há um processo persistente de uma solicitação para outra. Isso significa que, embora possa funcionar em um script CLI se o opcache estiver ativado, geralmente é inútil. A exceção é ao usar o pré-carregamento em bibliotecas FFI.
Note:
O pré-carregamento não é suportado no Windows.
A configuração do pré-carregamento envolve duas etapas e requer que o opcache esteja ativado. Primeiro, defina o valor opcache.preload em php.ini:
opcache.preload=preload.php
preload.php é um arquivo arbitrário que será executado uma vez na inicialização do servidor
(PHP-FPM, mod_php, etc.) e carregará o código na memória persistente. Em servidores que iniciam como
root antes de alternar para um usuário de sistema sem privilégios, ou se o PHP for executado como root
(não recomendado), o valor opcache.preload_user
pode especificar o usuário do sistema para executar o pré-carregamento. A execução do pré-carregamento como root
não é permitida por padrão. Configure opcache.preload_user=root
para permiti-lo explicitamente.
No script preload.php, qualquer arquivo referenciado por include,
include_once, require, require_once ou
opcache_compile_file() será analisado na memória persistente. No exemplo a seguir,
todos os arquivos .php no diretório src serão pré-carregados, a menos que
sejam um arquivo Test
.
<?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];
}
?>
Ambos include e opcache_compile_file()> funcionarão, mas têm implicações diferentes sobre como o código é tratado.
- include executará o código no arquivo, enquanto opcache_compile_file() não. Isso significa que apenas o primeiro suporta declaração condicional (funções declaradas dentro de um bloco if).
- Como includeexecutará o código, os arquivos includes aninhados também serão analisados e suas declarações pré-carregadas.
- opcache_compile_file() pode carregar arquivos em qualquer ordem. Ou seja, se
a.php define a classe
A
e b.php define a classeB
que estendeA
, então opcache_compile_file() pode carregar esses dois arquivos em qualquer ordem. Ao usar include, no entanto, a.php deve ser incluído primeiro. - Em ambos os casos, se um script posterior incluir um arquivo que já foi pré-carregado, seu conteúdo ainda será executado, mas quaisquer símbolos que ele definir não serão redefinidos. O uso de include_once não impedirá que o arquivo seja incluído uma segunda vez. Pode ser necessário carregar um arquivo novamente para incluir as constantes globais definidas nele, pois elas não são tratadas pelo pré-carregamento.