OPcache et JIT
OPcache fonctionne d'emblée avec OxPHP. Tous les threads worker PHP partagent un même segment de mémoire OPcache. Les scripts sont compilés une seule fois à la première exécution, puis servis depuis le cache par chaque worker ensuite. Aucune configuration particulière n'est nécessaire pour activer ce partage.
Fonctionnement d'OPcache avec OxPHP
OxPHP s'enregistre comme un SAPI nommé, et OPcache le traite exactement comme les autres SAPI serveur. Les caractéristiques principales sont :
- Cache partagé entre les workers : tous les threads worker PHP utilisent le même cache d'opcodes compilés. Un worker compile un fichier ; tous les workers en profitent.
- Aucune compilation par requête : après la première requête pour chaque script, les requêtes suivantes sautent entièrement l'étape d'analyse et de compilation.
opcache.enable_clin'a aucun effet sur OxPHP. Ce réglage ne s'applique qu'aux SAPI nommésclietphpdbg. OxPHP s'enregistre sous le nom de SAPIcli-server, si bien qu'OPcache est contrôlé uniquement viaopcache.enable. Le réglageopcache.enable_cliest utile si vous exécutez PHP CLI dans le même conteneur (par exemple, pour des migrations ou des commandes Artisan). L'image officielle OxPHP embarque PHP CLI aux côtés du binaire serveur, vous pouvez donc définiropcache.enable_cli=1si vos scripts CLI tirent parti de la mise en cache.
Pour activer OPcache, au minimum :
[opcache]
opcache.enable=1L'image Docker officielle d'OxPHP est basée sur php:*-zts-alpine, qui compile OPcache statiquement dans le binaire PHP. N'ajoutez PAS zend_extension=opcache à votre fichier INI. L'extension est déjà chargée, et ajouter cette ligne provoquera un avertissement à chaque démarrage de PHP. Seule la section de configuration [opcache] est nécessaire.
Réglages de production recommandés
Ces réglages sont optimisés pour les déploiements de conteneurs en production, où les fichiers PHP ne changent pas à l'exécution. Désactivez la validation des horodatages et préchargez les fichiers compilés au démarrage pour un débit maximal.
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.file_update_protection=0
opcache.jit_buffer_size=64M
opcache.jit=tracing| Réglage | Valeur recommandée | Description |
|---|---|---|
memory_consumption |
128 |
Mémoire partagée en Mo pour les scripts compilés. Augmentez-la si opcache_get_status() indique peu de mémoire libre. |
interned_strings_buffer |
16 |
Mémoire en Mo pour les chaînes internalisées partagées entre tous les workers. |
max_accelerated_files |
10000 |
Nombre maximal de scripts mis en cache. Définissez cette valeur au-dessus du nombre total de vos fichiers .php. |
validate_timestamps |
0 |
Lorsque la valeur est 0, OPcache ne vérifie jamais les changements sur le système de fichiers. Redémarrez le conteneur ou appelez opcache_reset() pour prendre en compte les modifications de code. |
revalidate_freq |
0 |
Secondes entre deux vérifications du système de fichiers. Sans effet lorsque validate_timestamps=0. |
file_update_protection |
0 |
Secondes après la modification d'un fichier avant qu'il ne soit éligible à la mise en cache. Réglez à 0 pour le mettre en cache immédiatement au démarrage. |
Réglages de développement
En développement, activez la validation des horodatages pour que les modifications de code prennent effet sans redémarrer le conteneur. Désactivez le JIT pour obtenir des traces d'appels plus claires lors du débogage.
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.jit_buffer_size=0
opcache.jit=disableAvec validate_timestamps=1, OPcache vérifie les dates de modification des fichiers toutes les revalidate_freq secondes. Cela ajoute une légère surcharge par requête, mais vous permet de modifier des fichiers PHP et de voir les changements dès la requête suivante.
C'est la stratégie de rechargement recommandée en mode développement pour OxPHP. OPcache effectue la vérification en ligne à chaque include, de sorte que les modifications de code sont prises en compte à la requête suivante, sans redémarrage du conteneur ni démon externe de surveillance de fichiers. Utilisez revalidate_freq=0 pour un stat à chaque include (précision maximale, un peu plus d'E/S), ou revalidate_freq=2 pour amortir le coût du stat. La valeur par défaut présentée ci-dessus offre un bon compromis, surtout si votre DOCUMENT_ROOT se trouve sur un bind-mount lent (Docker sur macOS/Windows).
Ce qui n'est PAS rechargé par validate_timestamps
Quelques catégories de changements exigent toujours un redémarrage du conteneur (ou un recyclage du worker), même avec validate_timestamps=1 :
- Les fichiers préchargés (
opcache.preload) sont liés au serveur au démarrage et ne sont jamais revalidés. Si vous modifiez un fichier préchargé, redémarrez le conteneur. - L'état de bootstrap du mode worker — en mode worker, l'autoloader, le conteneur d'injection de dépendances et tous les objets construits dans la portée externe résident dans la mémoire du worker. OPcache recompilera les fichiers de classe modifiés, mais le worker ne réexécutera pas son bootstrap. Pour les boucles worker en développement, appelez
Worker::scheduleExit()à la fin de chaque requête (par exemple derrière un indicateur d'environnementOXPHP_DEV) pour recycler le worker, ce qui réexécute la portée externe et prend en compte tous les changements. - Les caches au niveau du framework — conteneur Symfony compilé, cache de routes/config/vues de Laravel, classmap optimisée de Composer. Ce sont des fichiers
.phpqu'OPcache revalide, mais les valeurs qu'ils contiennent référencent des chemins de classe ou des identifiants de conteneur périmés. Exécutez la commandecache:cleardu framework ; OPcache seul ne suffit pas. - Les fichiers non-PHP —
.env,composer.json, config YAML/JSON, fichiers de templates compilés en dehors d'OPcache. OPcache ne suit que les fichiers qu'il a compilés ; tout le reste nécessite un redémarrage.
Compilation JIT
Le compilateur JIT d'OPcache traduit les opcodes PHP en code machine natif à l'exécution. Utilisez le mode tracing pour la meilleure optimisation :
opcache.jit=tracing
opcache.jit_buffer_size=64MLe JIT apporte le plus de bénéfice au code PHP limité par le CPU : boucles à forte charge mathématique, traitement de chaînes, manipulation d'images et rendu de templates. Pour les applications limitées par les E/S, qui passent l'essentiel de leur temps à attendre des requêtes de base de données ou des appels d'API externes, l'amélioration est minime.
Pour désactiver le JIT :
opcache.jit=disable
opcache.jit_buffer_size=0Préchargement
Le préchargement d'OPcache compile et met en cache les fichiers PHP au démarrage du serveur, avant que la moindre requête ne soit traitée. Cela élimine entièrement le coût de compilation à la première requête et rend les classes et les fonctions disponibles globalement, sans aucun coût de require ou d'autoload.
Configurez le préchargement dans votre fichier INI :
opcache.preload=/var/www/html/preload.php
opcache.preload_user=www-dataCréez un script preload.php qui charge vos fichiers les plus fréquemment utilisés :
<?php
// preload.php — runs once at server startup
require __DIR__ . '/vendor/autoload.php';
// Preload framework core files
$files = glob(__DIR__ . '/vendor/symfony/http-kernel/**.php');
foreach ($files as $file) {
opcache_compile_file($file);
}
// Preload hot application paths
opcache_compile_file(__DIR__ . '/src/Controller/ApiController.php');
opcache_compile_file(__DIR__ . '/src/Service/UserService.php');Les classes et fonctions préchargées sont disponibles en permanence pour toutes les requêtes. Elles ne peuvent pas être modifiées sans redémarrer le serveur.
Si vous utilisez le mode worker, votre application est déjà initialisée une seule fois : l'autoloader, la configuration et les connexions à la base de données persistent entre les requêtes. Le préchargement d'OPcache complète ce mécanisme en éliminant le coût de compilation des opcodes, mais il ne remplace pas l'initialisation de l'application. Les deux mécanismes fonctionnent indépendamment et peuvent être utilisés ensemble.
Application de la configuration PHP
OxPHP lit la configuration PHP depuis le répertoire standard conf.d. Utilisez un volume Docker ou une instruction COPY pour fournir votre fichier INI personnalisé.
docker run -p 80:80 \
-v ./custom.ini:/usr/local/etc/php/conf.d/custom.ini:ro \
ghcr.io/oxphp/oxphp:0.10.0FROM ghcr.io/oxphp/oxphp:0.10.0
COPY custom.ini /usr/local/etc/php/conf.d/custom.ini
COPY --chown=www-data:www-data . /var/www/htmlservices:
app:
image: ghcr.io/oxphp/oxphp:0.10.0
ports:
- "80:80"
volumes:
- ./custom.ini:/usr/local/etc/php/conf.d/custom.ini:ro
- ./src:/var/www/htmlSurveillance de l'état du cache
Inspectez l'état d'OPcache en direct depuis PHP pour vérifier qu'il fonctionne :
<?php
$status = opcache_get_status();
echo "Cached scripts: " . $status['opcache_statistics']['num_cached_scripts'] . "\n";
echo "Cache hits: " . $status['opcache_statistics']['hits'] . "\n";
echo "Cache misses: " . $status['opcache_statistics']['misses'] . "\n";
echo "Free memory: " . $status['memory_usage']['free_memory'] . " bytes\n";Si free_memory est constamment faible, augmentez opcache.memory_consumption.
Voir aussi
- Guide Docker -- configuration des conteneurs et montage des fichiers de configuration
- Référence de configuration -- variables d'environnement pour OxPHP
- Mode worker -- processus PHP persistants qui profitent le plus d'OPcache