Bien que PHP ne s'exécute pas comme un processus autonome démarré manuellement, il s'intègre étroitement avec des serveurs web tels qu'Apache. Cette synergie est rendue possible par une Interface de Programmation d'Application Serveur (SAPI), à l'instar du module mod_php pour Apache, qui assure la communication entre le serveur et l'interpréteur PHP.
L'architecture interne de PHP se décompose en trois composants fondamentaux : le Noyau PHP (PHP Core), le Moteur Zend (Zend Engine) et la couche des Extensions.
- Le Noyau PHP est responsable des opérations de bas niveau, telles que la gestion des requêtes HTTP, l'accès aux flux de fichiers et la manipulation des erreurs.
- Le Moteur Zend constitue le cœur de l'exécution. Sa tâche principale est de compiler le code source PHP en opcodes (code machine virtuel) et d'assurer leur exécution au sein de la machine virtuelle PHP.
- La couche des Extensions enrichit PHP avec des fonctionnalités spécialisées, offrant des fonctions, des classes et des bibliothèques pour des interactions spécifiques. Par exemple, l'extension
mysqliest nécessaire pour se connecter à une base de données MySQL.
Lors de l'exécution d'un script, le Moteur Zend peut ponctuellement céder le contrôle à une extension pour qu'elle exécute une tâche donnée. Une fois cette tâche accomplie, le contrôle est restitué au Moteur Zend, qui transmet à son tour le résultat au Noyau PHP. Ce dernier interagit ensuite avec la couche SAPI pour envoyer la réponse finale au client web.
Exploration Détaillée du Flux d'Exécution
Le fonctionnement interne de PHP est plus nuancé que cette description préliminaire. Analysons en profondeur les différentes phases qui constituent le cycle de vie d'une requête PHP.
Le démarrage de l'interpréteur PHP est généralement coïncident avec celui du serveur web. Ce processus d'initialisation se déroule en deux étapes distinctes :
- Une phase d'initialisation globale, dont les configurations demeurent valides pour toute la durée de vie du SAPI.
- Une phase d'initialisation spécifique, réitérée pour chaque requête entrante.
Phase d'Initialisation Globale (MINIT)
Cette première phase s'amorce dès le lancement du serveur web. PHP déclenche les méthodes MINIT (Module Initialization) de toutes les extensions activées et répertoriées dans le fichier php.ini.
La fonction MINIT a pour rôle d'initialiser les structures de données persistantes, ainsi que d'enregistrer les fonctions, les classes et les constantes qui seront accessibles pendant toute la durée de vie du processus PHP. Ces initialisations sont exécutées une seule fois par démarrage du SAPI.
Voici un exemple typique de la macro PHP_MINIT_FUNCTION :
PHP_MINIT_FUNCTION(mon_extension)
{
// Initialisation des ressources persistantes de l'extension.
// Enregistrement des fonctions et classes globales.
// Ces opérations sont effectuées une seule fois par démarrage du serveur.
return SUCCESS;
}
Phase d'Initialisation par Requête (RINIT)
Lorsqu'une requête HTTP parvient au serveur, la couche SAPI délègue le contrôle à l'interpréteur PHP. Ce dernier configure alors l'environnement nécessaire pour le traitement de la requête en cours.
Un tableau de symboles est créé pour conserver les variables spécifiques à cette requête (noms et valeurs). PHP invoque ensuite les méthodes RINIT (Request Initialization) de chaque extension active. Par exemple, si le module de gestion de session est activé, sa fonction RINIT se chargera d'initialiser la varible $_SESSION et de charger les données de session pertinentes. La méthode RINIT agit comme une étape de préparation automatique, exécutée avant l'interprétation du script PHP lui-même.
Exemple de la macro PHP_RINIT_FUNCTION :
PHP_RINIT_FUNCTION(mon_extension)
{
// Initialisation de variables spécifiques à la requête,
// telles que les variables de session, ou configuration d'un contexte unique.
// Cette fonction est appelée au début de chaque requête PHP.
return SUCCESS;
}
Phase de Nettoyage par Requête (RSHUTDOWN)
Dès que le script PHP a achevé son exécution (que ce soit en atteignant la fin du fichier ou suite à un appel explicite à exit() ou die()), PHP entame la procédure de nettoyage.
Il appelle séquentiellement la méthode RSHUTDOWN (Request Shutdown) de chaque extension. La fonction RSHUTDOWN a pour mission de libérer les ressources allouées pour la requête actuelle, ce qui inclut la destruction du tableau de symboles et l'appel de unset() sur toutes les variables utilisées durant l'exécution du script.
Exemple de la macro PHP_RSHUTDOWN_FUNCTION :
PHP_RSHUTDOWN_FUNCTION(mon_extension)
{
// Libération des ressources mémoire temporaires allouées
// spécifiquement pour la requête PHP en cours.
// Cette étape se déroule après l'exécution du script.
return SUCCESS;
}
Phase de Finalisation Globale (MSHUTDOWN)
Finalement, lorsque toutes les requêtes ont été traitées et que le SAPI se prépare à s'arrêter, PHP exécute la dernière phase de son cycle de vie.
Il déclenche la méthode MSHUTDOWN (Module Shutdown) de chaque extension. C'est lu'ltime opportunité pour les modules de libérer toute mémoire persistante ou tout gestionnaire de ressources qui aurait été initialisé lors de la phase MINIT.
Exemple de la macro PHP_MSHUTDOWN_FUNCTION :
PHP_MSHUTDOWN_FUNCTION(mon_extension)
{
// Libération des gestionnaires de fichiers ou des allocations mémoire
// globales et persistantes faites par l'extension.
// Ceci survient uniquement lors de l'arrêt du processus PHP.
return SUCCESS;
}
Il est important de souligner que les phases d'initialisation globale (MINIT) et de finalisation globale (MSHUTDOWN) ne sont exécutées qu'une seule fois par cycle de vie du processus PHP/SAPI, typiquement au démarrage et à l'arrêt du serveur web, et non pour chaque requête HTTP individuelle.