Zend OPcache: concetto, installazione e configurazione, con i valori di php.ini e la disattivazione di JIT

Ambiente di test Famiglia RHELAlmaLinux 9.8account rootVerificato il 2026-10-16

Zend OPcache è un'estensione di PHP che compila gli script PHP in bytecode e lo salva nella memoria condivisa, così la compilazione viene saltata quando lo stesso file viene eseguito di nuovo. Quando l'attivazione di JIT su un server WordPress con PHP 8.3 ha causato un errore 500 su tutte le pagine, il server è stato ripristinato lasciando OPcache com'era e disattivando solo JIT.

Da PHP 5.5 OPcache è incluso in PHP per impostazione predefinita.

1️⃣ Concetto di Zend OPcache: cache del bytecode

A ogni richiesta uno script PHP attraversa tre fasi: lettura del file, compilazione in bytecode ed esecuzione. Quando OPcache è attivo, dalla seconda richiesta per lo stesso file le prime due fasi spariscono e resta solo l'esecuzione.

La memoria condivisa in cui OPcache salva il bytecode è usata insieme da tutti i worker di PHP-FPM. Se allo stesso PHP-FPM sono collegati più siti, anche gli script di quei siti vengono salvati in un'unica memoria condivisa.

🧩 Elaborazione delle richieste senza e con OPcache
Diagramma esplicativo
🧠 OPcache
📨 Richiesta
🧰 PHP-FPM Worker
Worker 1Prima richiesta
Worker 2Seconda richiesta
Worker 3attesa
Tre fasi a ogni richiestaPrima richiesta · tre fasiSolo esecuzione→
⚙️ Elaborazione dello script PHP
Lettura del fileSaltata
→
Compilazione in bytecodeSaltata
→
EseguiEsecuzione di PHP · query al database
Memoria condivisa non usata↓ Bytecode salvato↑ Bytecode della memoria condivisa usato
🧠 Memoria condivisa
Bytecode (codice PHP compilato)
Usata insieme da tutti i worker di PHP-FPM · un'unica memoria condivisa anche con più siti
Senza OPcache, uno script PHP attraversa tre fasi a ogni richiesta: lettura del file, compilazione in bytecode ed esecuzione.
Senza OPcache, anche la seconda richiesta per lo stesso file attraversa di nuovo le tre fasi: lettura del file, compilazione in bytecode ed esecuzione.
Con OPcache attivo, la prima richiesta attraversa le tre fasi e poi salva il bytecode nella memoria condivisa.
Dalla seconda richiesta per lo stesso file le prime due fasi spariscono e resta solo l'esecuzione; la memoria condivisa è usata insieme da tutti i worker di PHP-FPM.

Ciò che OPcache salva è codice PHP compilato, quindi l'esecuzione di PHP e le query al database avvengono comunque a ogni apertura di una pagina. Saltare del tutto l'esecuzione di PHP salvando l'HTML già pronto è compito della cache di pagina.

2️⃣ Verificare l'installazione di PHP OPcache

Per sapere se OPcache è installato, guarda l'ultima riga dell'output di [php -v].

php -v
PHP 8.3.22 (cli) (built: Jun  3 2025 17:17:57) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.22, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.22, Copyright (c), by Zend Technologies

Se manca l'ultima riga, installalo con dnf. Il pacchetto di solito si chiama php-opcache; se hai installato più versioni di PHP insieme dal repository Remi, al nome si aggiunge la versione, come in php83-php-opcache.

dnf -y install php-opcache

Il pacchetto php-opcache del repository Remi carica l'estensione con la riga [zend_extension=opcache] di [/etc/php.d/10-opcache.ini]. Dopo l'installazione, riavvia PHP-FPM così OPcache si applica anche alle richieste web.

3️⃣ Configurazione di OPcache: valori di php.ini

Le impostazioni di OPcache possono stare in due posti: la sezione [opcache] di [/etc/php.ini] e [/etc/php.d/10-opcache.ini].

php --ini
Configuration File (php.ini) Path: /etc
Loaded Configuration File:         /etc/php.ini
Scan for additional .ini files in: /etc/php.d
Additional .ini files parsed:      /etc/php.d/10-opcache.ini,

I file della cartella php.d vengono letti dopo php.ini, quindi se la stessa voce è scritta in entrambi i posti vale il valore di php.d.

La tabella qui sotto mostra i valori predefiniti di PHP 8.3 e i valori applicati sul server WordPress esaminato.

VoceValore predefinito di PHP 8.3Valore applicatoSignificato
opcache.enable11Attiva OPcache
opcache.enable_cli01Usato anche da PHP da riga di comando (wp-cli ecc.)
opcache.memory_consumption1281024Memoria condivisa che salva il bytecode (MB)
opcache.interned_strings_buffer816Memoria che salva una sola volta le stringhe identiche (MB)
opcache.max_accelerated_files1000010000Limite massimo del numero di chiavi che si possono mettere in cache (il limite reale è un numero primo uguale o maggiore di questo valore: 16229 per 10000)
opcache.max_wasted_percentage510Se la memoria scarseggia e lo spazio sprecato supera questa percentuale, la cache viene svuotata e riavviata
opcache.validate_timestamps11Controlla se i file sono cambiati
opcache.revalidate_freq260Ogni quanto si controllano le modifiche ai file (secondi)
opcache.jittracingdisableModalità di JIT (da PHP 8.4 il valore predefinito è disable)
opcache.jit_buffer_size00Memoria di JIT; con 0 JIT non funziona (da PHP 8.4 il valore predefinito è 64M)

I valori inseriti nella sezione [opcache] di [/etc/php.ini] sono questi. La dimensione della memoria si sceglie in base alla memoria del server e [opcache.max_accelerated_files] in base al numero di file di WordPress.

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=1024
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.max_wasted_percentage=10
opcache.validate_timestamps=1
opcache.revalidate_freq=60

Se inserisci di nuovo una riga [zend_extension] in php.ini, l'estensione viene caricata due volte e compare l'avviso [Cannot load Zend OPcache].

Con [opcache.revalidate_freq] a 60, dopo la modifica di un file PHP il vecchio codice può continuare a essere eseguito per un massimo di 60 secondi.

Su un server WordPress in cui i file PHP cambiano spesso, lascia [opcache.validate_timestamps] a 1 in modo che le modifiche ai file vengano controllate. Lo 0 che la documentazione di Symfony consiglia per i server di produzione è adatto ai server in cui i file PHP cambiano solo quando si distribuisce una nuova versione.

Anche con [opcache.validate_timestamps] a 0, WordPress svuota da solo la cache dei file modificati quando aggiorni dalla schermata di amministrazione. Ma se aggiorni con wp-cli o modifichi i file via SSH, il vecchio codice continua a essere eseguito finché non riavvii PHP-FPM.

4️⃣ Disattivare JIT di OPcache

Il JIT di PHP 8 velocizza i lavori che richiedono molto calcolo alla CPU, quindi ha poco effetto in un'applicazione come WordPress, che gestisce richieste web. Anche nella misurazione con WordPress pubblicata nell'RFC su JIT di PHP, l'esecuzione con JIT attivo ha gestito 326 richieste al secondo e quella con JIT disattivato 315.

Su un server WordPress con PHP 8.3.22 è stato attivato JIT con [opcache.jit=tracing] e [opcache.jit_buffer_size=128M]. Tre giorni dopo, in un giorno in cui un'ondata di richieste ha fatto riavviare più volte i worker di PHP-FPM, si è verificato un errore 500 su tutte le pagine.

Nel registro degli errori è rimasto il messaggio [Allowed memory size of 1073741824 bytes exhausted]. Il [tried to allocate 4295229440 bytes] che lo segue è la registrazione di un tentativo di allocare 4 GB in una volta con un limite di memoria PHP di 1 GB. Dopo aver disattivato JIT, le stesse richieste sono state elaborate normalmente.

JIT si disattiva inserendo le due righe qui sotto in [/etc/php.d/10-opcache.ini]. Anche se in [/etc/php.ini] restano impostazioni di JIT, valgono i valori di questo file.

opcache.jit=disable
opcache.jit_buffer_size=0

In PHP 8.3 il valore predefinito di [opcache.jit_buffer_size] è 0, quindi se non lo imposti a parte JIT non funziona. Da PHP 8.4 anche il valore predefinito di [opcache.jit] è disable.

5️⃣ Applicare e verificare la configurazione

Le impostazioni modificate si applicano solo dopo il riavvio di PHP-FPM.

systemctl restart php-fpm

Dopo il riavvio la memoria condivisa di OPcache viene svuotata e riallocata con le nuove impostazioni.

php -i | grep -E '^opcache\.(enable|memory_consumption|revalidate_freq|validate_timestamps|jit) '
opcache.enable => On => On
opcache.jit => disable => disable
opcache.memory_consumption => 1024 => 1024
opcache.revalidate_freq => 60 => 60
opcache.validate_timestamps => On => On

I valori stampati da [php -i] sono le impostazioni di PHP da riga di comando. Nella famiglia RHEL anche PHP-FPM legge gli stessi file [/etc/php.ini] e [/etc/php.d], quindi i valori coincidono.

Se chiami [opcache_get_status()] dalla riga di comando, gli script in cache risultano 0. PHP da riga di comando crea una nuova memoria condivisa a ogni esecuzione, quindi l'uso di PHP-FPM si controlla mettendo il file qui sotto nella cartella dei documenti web e aprendolo dal browser.

<?php
header('Content-Type: text/plain');
$s = opcache_get_status(false);
print_r($s['memory_usage']);
print_r($s['opcache_statistics']);
print_r($s['interned_strings_usage']);
var_dump($s['cache_full']);

Se [cache_full] è true, la memoria condivisa o le chiavi sono piene. Dopo il controllo, elimina subito questo file.

Su un server in cui tre siti WordPress usano lo stesso PHP-FPM, erano in uso 317 MB dei 1024 MB di memoria condivisa. Gli script in cache erano da 3.366 a 4.222 per sito, 11.358 in tutto.

OPcache salva gli script con il percorso reale e, per i file caricati con un percorso relativo, crea un'altra chiave con la directory di lavoro aggiunta, quindi il numero di chiavi supera quello degli script. Con 11.358 script, le chiavi hanno riempito il limite di 16.229 e anche il buffer di stringhe da 16 MB non aveva più spazio libero.

Quando le chiavi sono piene, i nuovi script non vengono messi in cache e sono compilati a ogni richiesta. In 5 minuti e 21 secondi i cache miss sono passati da 18.408 a 36.027, ma il numero di script in cache è rimasto 11.358.

Su un server che gestisce più WordPress o molti plugin, imposta [opcache.max_accelerated_files] con margine in modo che il limite di chiavi non si riempia. Con 20000 il limite reale di chiavi diventa 32.531. Se il buffer di stringhe è pieno, aumenta anche [opcache.interned_strings_buffer].

🔢 FAQ & contenuti consigliati

Questa impostazione è stata rimossa in PHP 7.2, quindi in PHP 8 non ha effetto sul funzionamento anche se resta in php.ini. Su un server che ha ereditato vecchie impostazioni puoi eliminare questa riga.

OPcache salva codice PHP compilato, mentre la cache di oggetti di Redis salva i risultati delle query al database. Poiché salvano cose diverse, possono essere usati insieme.

Su un server che esegue PHP tramite PHP-FPM, OPcache lavora dentro PHP-FPM, quindi si riavvia solo PHP-FPM. Su un server che esegue PHP come modulo di Apache (mod_php), riavvia Apache.

ℹ️ Informativa sull'affiliazione
I contenuti di questo sito includono link di affiliazione. Se un visitatore acquista un prodotto o un servizio tramite uno di questi link, il sito riceve una commissione dal venditore. In questo processo l'importo pagato dall'acquirente (durante le promozioni l'importo scende↓) non aumenta. Prezzi, sconti e disponibilità indicati si riferiscono al momento della stesura e possono differire da quelli reali: prima di acquistare verifica sempre presso il venditore. I prodotti vengono scelti e valutati secondo criteri propri, e le commissioni non influiscono sull'ordine di presentazione né sul contenuto delle valutazioni.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Dimostra di essere umano: 10   +   1   =