28 votes

Où se trouve le point d'entrée principal de php-src/PHP-Internals ?

Quelle est la fonction ou le bout de code qui sert de point d'entrée principal pour l'exécution/interprétation d'un programme PHP dans le système de gestion de l'information ? source de PHP lui-même ? D'après ce que j'ai trouvé sur Google ou lu dans des livres, je sais que PHP est conçu pour fonctionner avec un serveur (même la commande CLI fonctionne en démarrant "the command line SAPI", qui agit comme un mini-serveur conçu pour traiter une seule requête), et que le serveur demandera à PHP d'exécuter un programme.

Je suis au courant de la minit y rinit fonctions du cycle de vie, qui servent de points d'entrée pour une Extension PHP .

Ce que je ne sais pas, c'est où le code source de PHP a cette conversation avec lui-même

Regardez, il y a un programme PHP dans ce fichier/chaîne. Je dois l'exécuter

Je n'essaie pas d'accomplir une tâche spécifique ici. J'essaie de comprendre comment l'interne de PHP fait ce qu'il fait, et de trouver un point d'entrée principal où je peux commencer à suivre son exécution.

51voto

axiac Points 13906

Où se trouve le point d'entrée du code d'une certaine SAPI ?

El CLI est une application autonome. Comme toute autre application écrite en C, son point d'entrée est la fonction main() (dossier sapi/cli/php_cli.c , ligne 1200 ):

int main(int argc, char *argv[])

Il existe deux versions du CLI pour Windows, l'une d'entre elles est une application console et démarre avec l'icône main() décrite ci-dessus, l'autre est une application Windows GUI (elle ne crée pas de console au démarrage et utilise des boîtes de messages pour la sortie) qui démarre avec la fonction WinMain() fonction (fichier sapi/cli/php_cli.c , ligne 1198 ).
main() y WinMain() utilisez le même code ici. Ils ont un nom différent et des fragments de code différents ici et là en vérifiant si le symbole PHP_CLI_WIN32_NO_CONSOLE est définie. Il est défini dans le fichier sapi/cli/cli_win32.c qui est utilisé pour générer l'application Windows GUI.
</Windows>

El CGI est également une application console autonome. Son point d'entrée est également le main() fonction dans le fichier sapi/cgi/cgi_main.c , ligne 1792 .

Similaire, le FPM version commence par main() dans le fichier sapi/fpm/fpm/fpm_main.c , ligne 1570 .

Gestionnaire Apache2 est un module chargeable dynamiquement ( .dll sur Windows, .so sur les systèmes de type Unix). Il enregistre certaines fonctions en tant que gestionnaires d'événements pour les événements publiés par le serveur Web (démarrage du serveur, pré/post configuration chargée, demande de processus, etc.) Ces gestionnaires sont enregistrés par la fonction php_ap2_register_hook() fonction dans le fichier sapi/apache2handler/sapi_apache2.c , ligne 738 .
(Vous pouvez trouver des détails sur la façon dont un module chargeable s'intègre à Apache dans le document Documentation Apache .)

Le gestionnaire qui nous intéresse est la fonction php_handler() qui est invoqué pour traiter une requête HTTP.

De la même manière, chaque SAPI possède un point d'entrée (soit main() ou une fonction qui est invoquée par le serveur web).

Tous ces points d'entrée effectuent un traitement similaire :

  • s'initialiser ;
  • analyser les arguments de la ligne de commande (seulement si c'est le cas) CLI , CGI ou tout autre type d'application autonome) ;
  • lire php.ini et/ou toute autre configuration qu'ils ont (la configuration du module Apache peut être remplacée dans le module .htaccess ) ;
  • créer un flux en utilisant le fichier d'entrée et le passer à la fonction php_execute_script() défini dans le fichier main/main.c , ligne 2496 ;
  • nettoyer et renvoyer un code de sortie au processus appelant (le shell ou le serveur web).

Où se trouve le code qui exécute réellement un script PHP ?

La fonction php_execute_script() est une enveloppe ; elle interprète les php.ini entrées de configuration auto_prepend_file y auto_append_file prépare la liste des fichiers (fichier auto-prepend, script principal, fichier auto-append) et transmet la liste à zend_execute_scripts() qui les traite.

php_execute_script() n'est pas toujours invoqué, certains SAPI et arguments de ligne de commande du CLI produisent l'invocation directe de zend_execute_scripts() .

zend_execute_scripts() c'est là que les choses intéressantes se produisent.

Il compile le fichier PHP (et renvoie une liste de Codes OP en op_array puis, si la compilation réussit (la valeur retournée est op_array n'est pas NULL ) il exécute les codes OP. Il y a aussi la gestion des exceptions et le nettoyage ; un travail ennuyeux mais aussi important que l'analyse syntaxique et les exécutions.

La compilation est un processus fastidieux. Elle est effectuée par la fonction zendparse() défini dans le fichier Zend/zend_language_parser.c . La définition de la zendparse() et le fichier Zend/zend_language_parser.c ne figurent nulle part dans le répertoire Git ; l'analyseur syntaxique est généré à l'aide de la fonction bison y re2c qui lisent les règles syntaxiques du langage et la définition des tokens lexicaux à partir de Zend/zend_language_parser.y y Zend/zend_language_scanner.l et générer le compilateur actuel dans le fichier Zend/zend_language_parser.c .

Cependant, même si le travail difficile n'est pas visible dans le repo, les parties intéressantes du processus de compilation sont visibles dans les fichiers mentionnés ci-dessus.

L'exécution du script compilé (la liste des codes OP) se fait par la fonction zend_execute() qui est défini dans le fichier Zend/zend_vm_execute.h . Il s'agit également d'un fichier généré et la partie intéressante est qu'il est généré par un script PHP.

Le générateur script ( Zend/zend_vm_gen.php ) utilise zend_vm_def.h y zend_vm_execute.skl pour générer zend_vm_execute.h y zend_vm_opcodes.h .

zend_vm_def.h contient le code d'interprétation réel qui est exécuté pour traiter chaque code OP.

Où se trouve le code d'une fonction fournie par le noyau de PHP ou l'une de ses extensions ?

Le code des fonctions PHP et des fonctions fournies par les extensions est en quelque sorte plus facile à suivre. Les fonctions incluses dans le noyau de PHP sont situées dans des fichiers du répertoire ext/standard les fonctions fournies par d'autres extensions sont situées dans des fichiers dans le répertoire correspondant ext des sous-répertoires.

Dans ces fichiers, les fonctions C qui implémentent les fonctions PHP sont déclarées à l'aide de l'attribut PHP_FUNCTION() macro. Par exemple, l'implémentation de la fonction PHP strpos() commence dans le fichier ext/standard/string.c , ligne 1948 . La fonction strchr() étant un alias de strstr() est déclaré à l'aide de l'élément PHP_FALIAS() macro dans le fichier ext/standard/basic_functions.c en ligne 2833 .

Et ainsi de suite, et ainsi de suite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X