Zend OPcache : concept, installation et configuration, avec les valeurs de php.ini et la désactivation de JIT
Zend OPcache est une extension PHP qui compile les scripts PHP en bytecode et le stocke en mémoire partagée, ce qui évite de recompiler lorsque le même fichier est exécuté de nouveau. Lorsque l'activation de JIT sur un serveur WordPress sous PHP 8.3 a provoqué une erreur 500 sur toutes les pages, le serveur a été rétabli en laissant OPcache tel quel et en désactivant seulement JIT.
Depuis PHP 5.5, OPcache est fourni avec PHP par défaut.
1️⃣ Concept de Zend OPcache : cache de bytecode
À chaque requête, un script PHP passe par trois étapes : lecture du fichier, compilation en bytecode et exécution. Quand OPcache fonctionne, les deux premières étapes disparaissent à partir de la deuxième requête pour le même fichier, et seule l'exécution reste.
La mémoire partagée dans laquelle OPcache stocke le bytecode est utilisée en commun par tous les workers de PHP-FPM. Si plusieurs sites sont reliés au même PHP-FPM, leurs scripts sont eux aussi stockés dans une seule mémoire partagée.
OPcache stocke du code PHP compilé : l'exécution de PHP et les requêtes à la base de données ont donc toujours lieu à chaque ouverture de page. Éviter complètement l'exécution de PHP en stockant le HTML terminé est le rôle d'un cache de pages.
2️⃣ Vérifier l'installation de PHP OPcache
Pour savoir si OPcache est installé, regardez la dernière ligne de la sortie de [php -v].
php -vPHP 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 TechnologiesSi cette dernière ligne est absente, installez-le avec dnf. Le paquet s'appelle généralement php-opcache ; si plusieurs versions de PHP ont été installées ensemble depuis le dépôt Remi, la version s'ajoute au nom, comme dans php83-php-opcache.
dnf -y install php-opcacheLe paquet php-opcache du dépôt Remi charge l'extension grâce à la ligne [zend_extension=opcache] de [/etc/php.d/10-opcache.ini]. Après l'installation, redémarrez PHP-FPM pour qu'OPcache s'applique aussi aux requêtes web.
3️⃣ Configuration d'OPcache : valeurs de php.ini
Les réglages d'OPcache peuvent se trouver à deux endroits : la section [opcache] de [/etc/php.ini] et [/etc/php.d/10-opcache.ini].
php --iniConfiguration 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,Les fichiers du dossier php.d sont lus après php.ini ; si la même directive figure aux deux endroits, c'est donc la valeur de php.d qui s'applique.
Le tableau ci-dessous présente les valeurs par défaut de PHP 8.3 et les valeurs appliquées sur le serveur WordPress examiné.
| Catégorie | Valeur par défaut de PHP 8.3 | Valeur appliquée | Signification |
|---|---|---|---|
| opcache.enable | 1 | 1 | Active OPcache |
| opcache.enable_cli | 0 | 1 | Utilisé aussi par PHP en ligne de commande (wp-cli, etc.) |
| opcache.memory_consumption | 128 | 1024 | Mémoire partagée qui stocke le bytecode (Mo) |
| opcache.interned_strings_buffer | 8 | 16 | Mémoire qui ne stocke qu'une seule fois les chaînes identiques (Mo) |
| opcache.max_accelerated_files | 10000 | 10000 | Limite supérieure du nombre de clés pouvant être mises en cache (la limite réelle est un nombre premier égal ou supérieur à cette valeur : 16229 pour 10000) |
| opcache.max_wasted_percentage | 5 | 10 | Si la mémoire manque et que l'espace gaspillé dépasse ce pourcentage, le cache est vidé puis redémarré |
| opcache.validate_timestamps | 1 | 1 | Vérifie si les fichiers ont changé |
| opcache.revalidate_freq | 2 | 60 | Fréquence de vérification des modifications de fichiers (secondes) |
| opcache.jit | tracing | disable | Mode de JIT (la valeur par défaut est disable à partir de PHP 8.4) |
| opcache.jit_buffer_size | 0 | 0 | Mémoire de JIT ; avec 0, JIT ne fonctionne pas (la valeur par défaut est 64M à partir de PHP 8.4) |
Les valeurs placées dans la section [opcache] de [/etc/php.ini] sont les suivantes. La taille de la mémoire se règle sur la mémoire du serveur, et [opcache.max_accelerated_files] sur le nombre de fichiers 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=60Si vous remettez une ligne [zend_extension] dans php.ini, l'extension est chargée deux fois et l'avertissement [Cannot load Zend OPcache] s'affiche.
Avec [opcache.revalidate_freq] à 60, l'ancien code peut continuer à s'exécuter jusqu'à 60 secondes après la modification d'un fichier PHP.
Sur un serveur WordPress où les fichiers PHP changent souvent, laissez [opcache.validate_timestamps] à 1 pour que les modifications de fichiers soient vérifiées. Le 0 que la documentation de Symfony recommande pour les serveurs de production convient aux serveurs où les fichiers PHP ne changent que lors du déploiement d'une nouvelle version.
Même avec [opcache.validate_timestamps] à 0, WordPress vide lui-même le cache des fichiers modifiés lorsque vous faites une mise à jour depuis l'écran d'administration. En revanche, si vous mettez à jour avec wp-cli ou modifiez des fichiers en SSH, l'ancien code continue de s'exécuter jusqu'au redémarrage de PHP-FPM.
4️⃣ Désactiver JIT d'OPcache
Le JIT de PHP 8 accélère les tâches qui demandent beaucoup de calcul au processeur ; son effet est donc faible pour une application comme WordPress, qui traite des requêtes web. Dans la mesure WordPress publiée dans la RFC sur JIT de PHP aussi, l'exécution avec JIT activé a traité 326 requêtes par seconde, celle avec JIT désactivé 315.
JIT a été activé sur un serveur WordPress sous PHP 8.3.22 avec [opcache.jit=tracing] et [opcache.jit_buffer_size=128M]. Trois jours plus tard, un jour où un afflux de requêtes a fait redémarrer plusieurs fois les workers de PHP-FPM, une erreur 500 est apparue sur toutes les pages.
Le journal d'erreurs contenait le message [Allowed memory size of 1073741824 bytes exhausted]. Le [tried to allocate 4295229440 bytes] qui le suit indique une tentative d'allouer 4 Go d'un coup avec une limite de mémoire PHP de 1 Go. Une fois JIT désactivé, les mêmes requêtes ont été traitées normalement.
JIT se désactive en mettant les deux lignes ci-dessous dans [/etc/php.d/10-opcache.ini]. Même si des réglages de JIT subsistent dans [/etc/php.ini], ce sont les valeurs de ce fichier qui s'appliquent.
opcache.jit=disable
opcache.jit_buffer_size=0Dans PHP 8.3, la valeur par défaut de [opcache.jit_buffer_size] est 0 ; sans réglage séparé, JIT ne fonctionne donc pas. À partir de PHP 8.4, la valeur par défaut de [opcache.jit] est aussi disable.
5️⃣ Appliquer et vérifier la configuration
Les réglages modifiés ne s'appliquent qu'après le redémarrage de PHP-FPM.
systemctl restart php-fpmAprès le redémarrage, la mémoire partagée d'OPcache est vidée, puis allouée de nouveau avec les nouveaux réglages.
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 => OnLes valeurs affichées par [php -i] sont celles de PHP en ligne de commande. Sur la famille RHEL, PHP-FPM lit les mêmes fichiers [/etc/php.ini] et [/etc/php.d], donc les valeurs sont identiques.
Si vous appelez [opcache_get_status()] en ligne de commande, le nombre de scripts en cache est de 0. PHP en ligne de commande crée une nouvelle mémoire partagée à chaque exécution ; l'utilisation de PHP-FPM se vérifie donc en plaçant le fichier ci-dessous dans le dossier des documents web et en l'ouvrant dans le navigateur.
<?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']);Si [cache_full] vaut true, la mémoire partagée ou les clés sont pleines. Une fois la vérification faite, supprimez ce fichier tout de suite.
Sur un serveur où trois sites WordPress utilisent le même PHP-FPM, 317 Mo des 1024 Mo de mémoire partagée étaient utilisés. Il y avait de 3 366 à 4 222 scripts en cache par site, soit 11 358 au total.
OPcache stocke les scripts sous leur chemin réel et, pour les fichiers chargés par un chemin relatif, crée une clé supplémentaire avec le répertoire de travail ajouté ; le nombre de clés dépasse donc celui des scripts. Avec 11 358 scripts, les clés ont atteint la limite de 16 229, et le tampon de chaînes de 16 Mo n'avait lui aussi plus d'espace libre.
Quand les clés sont pleines, les nouveaux scripts ne sont pas mis en cache et sont compilés à chaque requête. En 5 minutes et 21 secondes, les échecs de cache sont passés de 18 408 à 36 027, mais le nombre de scripts en cache est resté à 11 358.
Sur un serveur qui fait tourner plusieurs WordPress ou beaucoup de plugins, réglez [opcache.max_accelerated_files] largement pour que la limite de clés ne soit pas atteinte. Avec 20000, la limite réelle de clés est de 32 531. Si le tampon de chaînes est plein, augmentez aussi [opcache.interned_strings_buffer].
🔢 FAQ & contenus recommandés
Cache
Cache : définition et tous les domaines où la mise en cache est utilisée
Un article qui répartit les domaines où l'on utilise des caches, dont OPcache, qui stocke du code PHP compilé, et le cache de pages, qui stocke du HTML terminé.
PHP-FPM
Avertissement php-fpm max_children : trouver la cause dans les journaux avant d'ajouter des workers
Un article qui permet de retrouver dans les journaux la cause de l'avertissement qui apparaît quand tous les workers de PHP-FPM partageant la mémoire partagée d'OPcache sont occupés.
PHP-FPM
Qu’est-ce que PHP-FPM | Installer et configurer PHP-FPM
Un article sur l'installation de PHP-FPM, à l'intérieur duquel fonctionne OPcache, sur la configuration du pool dans www.conf et sur la manière de le redémarrer.
ℹ️ Mention d'affiliation
Le contenu de ce site contient des liens d'affiliation. Lorsqu'un visiteur achète un produit ou un service via l'un de ces liens, le site perçoit une commission du vendeur. Le montant payé par l'acheteur(il baisse lors des promotions ↓), lui, n'augmente pas. Les prix, remises et stocks indiqués correspondent à la date de rédaction et peuvent différer ; vérifiez-les donc auprès du vendeur avant d'acheter. Les produits sont choisis et évalués selon nos propres critères, et les commissions n'influencent ni l'ordre de présentation ni le contenu des évaluations.