# Comment PHP génère une page web : le trajet d'une requête

> Comment fonctionne PHP ? Du clic à la page finale, via serveur web, SAPI, compilateur et Zend VM : sept étapes expliquées avec des exemples.

Source : https://phpsos.de/fr/php/wie-php-funktioniert/  
État : 25/10/2026  
Fournisseur : PHP SOS, Assistance d'urgence PHP et sécurité des serveurs. Aide immédiate par WhatsApp : https://wa.me/491736494914?text=Bonjour%20PHP%20SOS%2C%20nous%20avons%20besoin%20d%27aide%20avec%20notre%20serveur%20PHP.%20Entreprise%20%3A%20%E2%80%A6%20Site%20web%20%3A%20%E2%80%A6

**En bref :** lorsqu'un navigateur demande une page PHP, le serveur web accepte la requête et la transmet à PHP via une interface (SAPI). PHP traduit le script en bytecode, l'exécute dans la Zend Engine et renvoie le résultat, le plus souvent du HTML, au serveur web. L'état de la requête est ensuite nettoyé, pour que la suivante démarre proprement.

## Que se passe-t-il quand quelqu'un appelle votre site web ?

Pour le visiteur, ce n'est qu'un clic. Sur le serveur, de nombreuses étapes s'enchaînent en quelques millisecondes. Connaître ce déroulement aide à comprendre pourquoi les mises à jour, les redémarrages et la configuration sont si importants, et pourquoi une faille dans PHP lui-même pèse plus lourd qu'une faille dans un plugin.

Le manuel PHP cite trois éléments nécessaires pour un site PHP : l'interpréteur PHP (en CGI ou en module serveur), un serveur web et un navigateur. L'interpréteur est le programme qui lit et exécute le code PHP. La façon dont il est relié au serveur web détermine le mode d'exécution.

## Comment fonctionne PHP ? Sept étapes d'une requête

1. **Requête :** le navigateur envoie une requête HTTP, par exemple `GET /kontakt.php`, au serveur.
2. **Serveur web :** Apache, Nginx ou LiteSpeed acceptent la requête. Ils livrent eux-mêmes les fichiers statiques comme les images. Pour les fichiers `.php`, ils appellent PHP.
3. **Transmission via la SAPI :** l'interface serveur (SAPI) transmet à PHP les données de la requête, comme les en-têtes, les paramètres et les données de formulaire. Avec PHP-FPM, cela se fait via le protocole FastCGI ; avec mod_php, directement dans le processus Apache. Détails sous [SAPI expliquée](https://phpsos.de/fr/php/sapi-erklaert/).
4. **Préparer la requête :** PHP place les données de la requête dans des variables comme `$_GET`, `$_POST`, `$_COOKIE` et `$_FILES` et réserve de la mémoire pour la requête.
5. **Traduire :** le script est décomposé en éléments (tokens), il en résulte un arbre syntaxique abstrait (AST), puis des opcodes, sorte de langage machine pour PHP. Si OPcache est actif, cette étape est sautée lorsque le script est déjà dans le cache.
6. **Exécuter :** la machine virtuelle de la [Zend Engine](https://phpsos.de/fr/php/zend-engine/) traite les opcodes, interroge les bases de données, lit des fichiers et produit la sortie.
7. **Réponse et nettoyage :** la sortie retourne au serveur web via la SAPI, puis au navigateur. PHP libère ensuite la mémoire de la requête et réinitialise l'état.

L'AST existe depuis PHP 7. Selon le RFC correspondant, l'analyseur produisait auparavant les opcodes directement pendant la lecture ; la séparation en trois phases a rendu le compilateur plus facile à maintenir.

## Un exemple : ce que le script voit de la requête

Le script inoffensif suivant montre quelles informations PHP reçoit de la requête et dans quel mode d'exécution il tourne :

```php
<?php
header('Content-Type: text/plain; charset=utf-8');

echo 'Betriebsart (SAPI): ' . PHP_SAPI . "\n";
echo 'PHP-Version: ' . PHP_VERSION . "\n";
echo 'Methode: ' . ($_SERVER['REQUEST_METHOD'] ?? '-') . "\n";
echo 'Speicher in dieser Anfrage: ' . memory_get_usage() . " Bytes\n";
```

Sur un serveur avec PHP-FPM, `PHP_SAPI` renvoie la valeur `fpm-fcgi` ; sous Apache avec mod_php, `apache2handler`. Ne laissez de tels fichiers de test que brièvement dans le répertoire public, jamais en permanence, car les indications de version aident aussi les attaquants à s'orienter.

## Où interviennent le cache de bytecode et le JIT

La traduction de l'étape 5 prend du temps. Selon le manuel, l'[OPcache](https://phpsos.de/fr/php/opcache/) stocke du bytecode précompilé dans la mémoire partagée et évite ainsi à PHP de charger et de décomposer les scripts à chaque requête. Depuis PHP 8.0, un compilateur JIT peut en outre produire du véritable code machine à partir des opcodes. Selon le RFC sur le JIT, il constitue une partie presque autonome d'OPcache.

| Phase | Résultat | Mis en cache ? |
|---|---|---|
| Analyse lexicale | flux de tokens | non |
| Analyse syntaxique | arbre syntaxique abstrait (AST) | non |
| Compilation | opcodes (op arrays par fichier et par fonction) | oui, dans OPcache |
| JIT (facultatif) | code machine | oui, dans la mémoire d'OPcache |
| Exécution | sortie de la page | non |

Le cache ne concerne que le code traduit. Les données propres à chaque requête, comme les saisies de formulaire ou les valeurs de session, ne sont pas partagées via OPcache.

## Pourquoi PHP2Shell agit précisément dans ce déroulement

Les deux failles PHP2Shell ne touchent pas une application, mais le déroulement lui-même. Avec CVE-2026-109618, un état de mémoire insuffisante (out of memory) peut interrompre PHP alors que les données de la requête ne sont que partiellement préparées, donc à l'étape 4. Lors du nettoyage qui suit, des données invalides peuvent alors être traitées comme valides.

Avec CVE-2026-109619, l'état interne d'une requête peut subsister après la libération de la mémoire. Une requête ultérieure dans le même worker peut l'utiliser avant qu'il ne soit réinitialisé. Cela concerne l'étape 7, le nettoyage. Le contexte figure sur la page [CVE-2026-109619](https://phpsos.de/fr/php2shell/cve-2026-109619/) et dans l'article sur le [cycle de vie d'une requête](https://phpsos.de/fr/php/request-lebenszyklus/).

Il en résulte que les mesures de protection dans le code de l'application, comme les plugins de sécurité, n'interviennent qu'à l'étape 6. Avec mod_php, l'équipe PHP a même démontré un exploit avant que le code de l'application ne s'exécute. Seule est efficace la mise à jour de PHP vers 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, suivie d'un redémarrage de tous les processus PHP, car les workers de longue durée continuent sinon d'exécuter l'ancien code.

## Comment PHP SOS aide-t-il concrètement ?

- **Rendre le déroulement visible :** nous déterminons quel mode d'exécution, quelle configuration et quel cache sont réellement actifs sur votre serveur.
- **Mettre à jour correctement :** nous installons la mise à jour de PHP et vérifions, grâce aux heures de démarrage, qu'aucun ancien processus ne tourne plus.
- **Sécuriser les couches :** dans le cadre du [durcissement de serveur](https://phpsos.de/fr/leistungen/server-haertung/), nous limitons les tailles de requêtes, la mémoire et les droits là où ils agissent : avant le code de l'application.
- **Rechercher des traces :** pour les serveurs accessibles sans protection, nous recherchons des signes d'intrusion.


## Questions fréquentes

**Le code PHP est-il retraduit à chaque appel ?**  
Sans cache, oui : PHP décompose le script, construit un arbre syntaxique et en produit des opcodes. Avec OPcache actif, les opcodes sont conservés dans la mémoire partagée et réutilisés tant que le fichier n'a pas changé.

**Que reste-t-il en mémoire après une requête ?**  
En principe, l'état d'une requête est nettoyé à la fin, afin que la requête suivante démarre proprement. Seuls certains éléments, comme OPcache ou les connexions persistantes, sont durables. C'est précisément ce nettoyage que vise CVE-2026-109619.

**Pourquoi faut-il redémarrer PHP après une mise à jour ?**  
Avec PHP-FPM et mod_php, des processus tournent en permanence et ont chargé l'ancien code du programme. De nouveaux fichiers sur le disque n'y changent rien. Seul un redémarrage charge le code corrigé.

**Un serveur web sans PHP est-il plus sûr ?**  
Il offre une surface d'attaque plus réduite, puisqu'aucune logique de programme ne réagit aux requêtes. Pour des contenus purement statiques, c'est une vraie option. Mais pour les boutiques, les formulaires et les connexions, il faut un langage côté serveur, et sa maintenance compte alors.

## Sources

- [Manuel PHP : introduction](https://www.php.net/manual/en/introduction.php)
- [PHP RFC: Abstract Syntax Tree](https://wiki.php.net/rfc/abstract_syntax_tree)
- [PHP RFC: JIT](https://wiki.php.net/rfc/jit)
- [Manuel PHP : OPcache](https://www.php.net/manual/en/book.opcache.php)
