Cet article a été revu par des pairs par Younes Rafie. Merci à tous les pairs examinateurs de SitePoint pour avoir fait du contenu SitePoint le meilleur possible!
Inspiré par un article récent sur la façon dont le code Ruby s'exécute, cet article couvre le processus d'exécution du code PHP.
Les plats clés
- L'exécution du code PHP implique quatre étapes: lexing, l'analyse, la compilation et l'interprétation. Chaque étape est cruciale dans le processus de conversion du code source PHP en code lisible par machine.
- lexing, ou tokenising, est le processus de transformation d'une chaîne (code source PHP) en une séquence de jetons. Chaque jeton est un identifiant nommé pour la valeur qu'il a égalée. Cette étape stocke également le lexème et le numéro de ligne du jeton correspondant.
- L'étape d'analyse vérifie la validité de l'ordre du jeton et génère l'arbre de syntaxe abstrait (AST). L'AST est une vue d'arbre du code source utilisé pendant l'étape de compilation.
- L'étape de compilation émet des opcodes en traversant l'AST et effectue des optimisations comme la résolution des appels de fonction avec des arguments littéraux et le pliage des expressions mathématiques constantes. La sortie de cette étape peut être inspectée à l'aide d'Opcache, de VLD et de phpdbg.
- L'étape d'interprétation est la dernière étape où les opcodes sont exécutés sur la machine virtuelle Zend Engine (ZE). La sortie de cette étape est ce que votre script PHP sort via des commandes telles que Echo, Print, Var_dump, etc.
Introduction
Il se passe beaucoup de choses sous le capot lorsque nous exécutons un morceau de code PHP. D'une manière générale, l'interprète PHP passe par quatre étapes lors de l'exécution du code:
- lexing
- analyse
- Compilation
- Interprétation
Cet article parcourra ces étapes et montrera comment nous pouvons voir la sortie de chaque étape pour vraiment voir ce qui se passe. Notez que bien que certaines des extensions utilisées devraient déjà faire partie de votre installation PHP (comme le tokenizer et l'opcache), d'autres devront être installés et activées manuellement (comme PHP-AST et VLD).
Étape 1 - Lexing
lexing (ou tokenising) est le processus de transformation d'une chaîne (code source PHP, dans ce cas) en une séquence de jetons. Un jeton est simplement un identifiant nommé pour la valeur qu'il a égalée. PHP utilise RE2C pour générer son lexer à partir du fichier de définition zend_language_scanner.l.
Nous pouvons voir la sortie de l'étape de lexing via l'extension du tokenizer:
$code = <span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>$tokens = token_get_all($code); </span></span><span> </span><span><span>foreach ($tokens as $token) { </span></span><span> <span>if (is_array($token)) { </span></span><span> <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL; </span></span><span> <span>} else { </span></span><span> <span>var_dump($token); </span></span><span> <span>} </span></span><span><span>} </span></span>
Sorties:
$code = <span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>$tokens = token_get_all($code); </span></span><span> </span><span><span>foreach ($tokens as $token) { </span></span><span> <span>if (is_array($token)) { </span></span><span> <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL; </span></span><span> <span>} else { </span></span><span> <span>var_dump($token); </span></span><span> <span>} </span></span><span><span>} </span></span>
Il y a quelques points notables de la sortie ci-dessus. Le premier point est que toutes les pièces du code source ne sont pas nommées de jetons. Au lieu de cela, certains symboles sont considérés comme des jetons en eux-mêmes (tels que =, ;,:,?, Etc.). Le deuxième point est que le Lexer fait en fait un peu plus que simplement la sortie d'un flux de jetons. Il est également, dans la plupart des cas, stocke le lexème (la valeur correspondante par le jeton) et le numéro de ligne du jeton correspondant (qui est utilisé pour des choses comme les traces de pile).
Étape 2 - Parsing
L'analyseur est également généré, cette fois avec le bison via un fichier de grammaire BNF. PHP utilise une grammaire sans contexte LALR (1) (regardez vers l'avenir, gauche à droite). La partie à l'avance signifie simplement que l'analyseur est en mesure de regarder n jetons à venir (1, dans ce cas) pour résoudre les ambiguïtés qu'elle peut rencontrer pendant l'analyse. La partie de gauche à droite signifie qu'elle analyse le flux de jeton de gauche à droite.
L'étape d'analyse générée prend le flux de jetons du Lexer en entrée et a deux travaux. Il vérifie d'abord la validité de l'ordre des jetons en essayant de les faire correspondre à l'une des règles de grammaire définies dans son fichier de grammaire BNF. Cela garantit que des constructions de langage valides sont formées par les jetons dans le flux de jetons. Le deuxième travail de l'analyseur consiste à générer l'arbre de syntaxe abstrait (AST) - une vue d'arbre du code source qui sera utilisé au cours de la prochaine étape (compilation).
Nous pouvons afficher une forme de l'AST produit par l'analyseur en utilisant l'extension PHP-AST. L'AST interne n'est pas directement exposé car il n'est pas particulièrement «propre» pour fonctionner (en termes de cohérence et d'utilisation générale), et donc l'extension PHP-AST effectue quelques transformations sur elle pour rendre plus agréable à travailler.
Jetons un coup d'œil à l'AST pour un morceau de code rudimentaire:
Line 1: T_OPEN_TAG ('<?php ') Line 2: T_VARIABLE ('$a') Line 2: T_WHITESPACE (' ') string(1) "=" Line 2: T_WHITESPACE (' ') Line 2: T_LNUMBER ('1') string(1) ";"
Sortie:
$code = <span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>print_r(ast<span>\parse_code</span>($code, 30)); </span></span>
Les nœuds d'arborescence (qui sont généralement de type ASTNode) ont plusieurs propriétés:
- KING - Une valeur entière pour représenter le type de nœud; Chacun a une constante correspondante (par exemple AST_STMT_LIST => 132, AST_ASSIGN => 517, AST_VAR => 256)
- Flags - Un entier qui spécifie le comportement surchargé (par exemple, un nœud astast_binary_op aura des drapeaux pour différencier le fonctionnement binaire qui se produit)
- Lineno - Le numéro de ligne, comme le montre les informations de jeton plus tôt
- Enfants - Sub nœuds, généralement des parties du nœud décomposés (par exemple, un nœud de fonction aura les enfants: paramètres, type de retour, corps, etc.)
La sortie AST de cette étape est prête à travailler pour des outils tels que les analyseurs de code statique (par exemple Phan).
Étape 3 - Compilation
L'étape de compilation consomme l'AST, où il émet des opcodes en traversant récursivement l'arbre. Cette étape effectue également quelques optimisations. Il s'agit notamment de résoudre certains appels de fonction avec des arguments littéraux (tels que Strlen ("ABC") à int (3)) et le pliage des expressions mathématiques constantes (telles que 60 * 60 * 24 à int (86400)).
Nous pouvons inspecter la sortie OPCode à ce stade de plusieurs façons, y compris avec Opcache, VLD et PHPDBG. Je vais utiliser VLD pour cela, car je pense que la sortie est plus sympathique à regarder.
Voyons quelle est la sortie pour le script file.php suivant:
$code = <span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>$tokens = token_get_all($code); </span></span><span> </span><span><span>foreach ($tokens as $token) { </span></span><span> <span>if (is_array($token)) { </span></span><span> <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL; </span></span><span> <span>} else { </span></span><span> <span>var_dump($token); </span></span><span> <span>} </span></span><span><span>} </span></span>
Exécution de la commande suivante:
Line 1: T_OPEN_TAG ('<?php ') Line 2: T_VARIABLE ('$a') Line 2: T_WHITESPACE (' ') string(1) "=" Line 2: T_WHITESPACE (' ') Line 2: T_LNUMBER ('1') string(1) ";"
Notre sortie est:
$code = <span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>print_r(ast<span>\parse_code</span>($code, 30)); </span></span>
Les OPCodes ressemblent au code source d'origine, suffisamment pour suivre les opérations de base. (Je ne vais pas plonger dans les détails d'Opcodes dans cet article, car cela prendrait plusieurs articles entiers en soi.) en a fait en résolvant la condition constante (php_version === '7.1.0-dev') à true.
OPCACHE fait plus que la simple mise en cache OPCodes (en contournant ainsi les étapes de lexing, d'analyse et de compilation). Il regorge également de nombreux niveaux d'optimisations différents. Passons au niveau d'optimisation à quatre passes pour voir ce qui sort:
Commande:
ast\Node Object ( [kind] => 132 [flags] => 0 [lineno] => 1 [children] => Array ( [0] => ast\Node Object ( [kind] => 517 [flags] => 0 [lineno] => 2 [children] => Array ( [var] => ast\Node Object ( [kind] => 256 [flags] => 0 [lineno] => 2 [children] => Array ( [name] => a ) ) [expr] => 1 ) ) ) )
Sortie:
<span>if (PHP_VERSION === '7.1.0-dev') { </span> <span>echo 'Yay', PHP_EOL; </span><span>} </span>
Nous pouvons voir que la condition constante a été supprimée et que les deux instructions d'écho ont été compactées en une seule instruction. Ce ne sont qu'un avant-goût des nombreuses optimisations que l'opcache s'applique lors de l'exécution de passes sur les opcodes d'un script. Je ne passerai pas par les différents niveaux d'optimisation dans cet article, car ce serait également un article en soi.
Étape 4 - Interprétation
L'étape finale est l'interprétation des opcodes. C'est là que les opcodes sont exécutés sur la machine virtuelle Zend Engine (ZE). Il y a en fait très peu de choses à dire sur cette étape (d'un point de vue de haut niveau, au moins). La sortie est à peu près tout ce que votre script PHP sort via des commandes telles que Echo, Print, Var_dump, etc.
Donc, au lieu de creuser dans quelque chose de complexe à ce stade, voici un fait amusant: PHP se demande comme une dépendance lors de la génération de sa propre machine virtuelle. En effetConclusion
Nous avons jeté un bref aperçu des quatre étapes que l'interprète PHP passe lors de l'exécution du code PHP. Cela a impliqué l'utilisation de diverses extensions (y compris le tokenizer, le php-ast, l'opcache et le VLD) pour manipuler et afficher la sortie de chaque étape.
J'espère que cet article a contribué à vous fournir une meilleure compréhension holistique de l'interprète de PHP, ainsi que l'importance de l'extension Opcache (pour ses capacités de mise en cache et d'optimisation).
Questions fréquemment posées (FAQ) sur le processus d'exécution PHP
Quel est le rôle de l'interprète PHP dans le processus d'exécution?
L'interprète PHP joue un rôle crucial dans le processus d'exécution PHP. Il est responsable de la conversion du code source PHP en code lisible par machine. L'interprète lit la ligne de script PHP ligne par ligne, interprète chaque ligne et effectue les opérations nécessaires. Il est également responsable de la gestion des erreurs et des exceptions pendant le processus d'exécution. L'interprète PHP est un composant clé de l'environnement d'exécution PHP, qui comprend également le serveur Web et les extensions PHP.
Comment fonctionne le moteur PHP?
Le moteur PHP est le cœur de le processus d'exécution PHP. Il est responsable de l'analyse du script PHP, de la compilation en bytecode, puis de l'exécution du bytecode. Le moteur PHP utilise un processus en deux étapes pour exécuter des scripts PHP. Tout d'abord, il analyse le script PHP et le convertit en une arborescence de syntaxe abstraite (AST). Ensuite, il compile l'AST en bytecode et l'exécute. Le moteur PHP comprend également un gestionnaire de mémoire et un collecteur de déchets pour gérer l'utilisation de la mémoire pendant le processus d'exécution.
Quelle est la différence entre l'interface de ligne de commande de PHP et l'interface du serveur Web?
La commande PHP de PHP - Interface de ligne (CLI) et l'interface du serveur Web sont deux façons différentes d'exécuter des scripts PHP. La CLI est utilisée pour exécuter des scripts PHP à partir de la ligne de commande, tandis que l'interface du serveur Web est utilisée pour exécuter des scripts PHP en réponse aux demandes Web. La principale différence entre les deux interfaces est la façon dont ils gèrent l'entrée et la sortie. Dans la CLI, l'entrée est lue à partir de la ligne de commande et la sortie est écrite sur la console. Dans l'interface du serveur Web, l'entrée est lue à partir de la demande HTTP et la sortie est écrite dans la réponse HTTP.
Comment PHP gère-t-il les erreurs pendant le processus d'exécution?
PHP a une gestion des erreurs robuste mécanisme qui lui permet de gérer les erreurs pendant le processus d'exécution. Lorsqu'une erreur se produit, PHP génère un message d'erreur et l'envoie au gestionnaire d'erreur. Le gestionnaire d'erreur peut afficher le message d'erreur, le enregistrer ou l'ignorer, en fonction des paramètres de rapport d'erreur. PHP prend également en charge la manipulation des exceptions, ce qui lui permet de gérer les erreurs de manière plus structurée et gérable.
Quel est le rôle des extensions de PHP dans le processus d'exécution?
Les extensions PHP sont des modules qui ajoutent de nouvelles fonctionnalités et fonctionnalités au langage PHP. Ils sont chargés dans l'environnement d'exécution PHP pendant le processus d'exécution et peuvent être utilisés pour effectuer une large gamme de tâches, de l'accès à la base de données au traitement d'image. Les extensions de PHP sont écrites en C et sont compilées en code machine, ce qui les rend très rapides et efficaces. Ils sont un composant clé de l'écosystème PHP et contribuent à sa flexibilité et à sa puissance.
Comment PHP optimise-t-il le processus d'exécution?
PHP utilise plusieurs techniques pour optimiser le processus d'exécution. L'une de ces techniques est la mise en cache Opcode, qui implique le stockage du bytecode généré par le moteur PHP en mémoire afin qu'il puisse être réutilisé dans les exécutions suivantes. Cela élimine la nécessité d'analyser et de compiler le script PHP à chaque fois qu'il est exécuté, ce qui entraîne des améliorations de performances significatives. PHP utilise également la compilation JIT-Time (JIT), qui consiste à compiler des bytecodes dans le code machine à l'exécution pour améliorer davantage les performances.
Comment PHP gère-t-il la gestion de la mémoire pendant le processus d'exécution?
PHP possède un gestionnaire de mémoire intégré qui gère l'allocation de mémoire et la transmission pendant le processus d'exécution. Le gestionnaire de mémoire alloue la mémoire pour les variables et les structures de données selon les besoins, et traite la mémoire lorsqu'elle n'est plus nécessaire. PHP a également un collecteur de déchets qui libère automatiquement de la mémoire qui n'est plus utilisée. Cela aide à prévenir les fuites de mémoire et à maintenir l'utilisation de la mémoire sous contrôle.
Quel est le rôle du serveur Web dans le processus d'exécution PHP?
Le serveur Web joue un rôle clé dans l'exécution PHP processus. Il est responsable de la gestion des demandes HTTP, de l'exécution de scripts PHP en réponse à ces demandes et de renvoyer des réponses HTTP au client. Le serveur Web travaille en étroite collaboration avec l'interprète PHP et le moteur PHP pour exécuter des scripts PHP et générer des pages Web dynamiques. Les serveurs Web les plus couramment utilisés pour PHP sont Apache et Nginx.
Comment PHP gère-t-il les interactions de la base de données pendant le processus d'exécution?
PHP a une prise en charge intégrée pour une large gamme de bases de données, y compris MySQL, PostgreSQL et SQLite. Il utilise des extensions spécifiques à la base de données pour interagir avec ces bases de données pendant le processus d'exécution. Ces extensions fournissent un ensemble de fonctions qui peuvent être utilisées pour se connecter à la base de données, exécuter les requêtes SQL, récupérer les résultats et gérer les erreurs. PHP prend également en charge l'extension PDO (PHP Data Objectts), qui fournit une interface de base de données-indésirable pour les interactions de base de données.
Comment PHP gère la gestion des sessions pendant le processus d'exécution?
PHP a une prise en charge intégrée pour la gestion de session, ce qui lui permet de maintenir l'état entre les différentes demandes HTTP. Lorsqu'une session est démarrée, PHP crée un identifiant de session unique et le stocke dans un cookie sur le navigateur du client. Cet ID de session est ensuite renvoyé au serveur avec chaque demande suivante, permettant à PHP d'identifier le client et de récupérer les données de session correspondantes. Les fonctionnalités de gestion de session de PHP facilitent la mise en œuvre de l'authentification des utilisateurs, des paniers d'achat et d'autres fonctionnalités d'état dans les applications Web.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Phpidentifiesauser'sessionusingssse cookiesand sessionids.1) whenSession_start () est calculé, phpgeneratesauquesseSessionIdStoredInacookIenameDPhpSesssIdonUser'sbrowser.2) thisIdallowsphptoreTrrieSeSessionDatafromTeserver.

La sécurité des sessions PHP peut être obtenue grâce aux mesures suivantes: 1. Utilisez Session_RegeReate_ID () pour régénérer l'ID de session lorsque l'utilisateur se connecte ou est une opération importante. 2. Cryptez l'ID de session de transmission via le protocole HTTPS. 3. Utilisez session_save_path () pour spécifier le répertoire sécurisé pour stocker les données de session et définir correctement les autorisations.

PhpSessionFilesArestorentheDirectorySpecifiedSession.save_path, généralement / tmponunix-likesystemsorc: \ windows \ temponwindows.tocustomzethis: 1) usession_save_path () tosetacustomDirectory, astumeit'swrit

ToretrrievedatafromaphpSession, startTheSessionwithSession_start () et accessvariablesInthe $ _sessionArray.forexample: 1) startTheSession: session_start (). 2) récupéré: $ username = $ _ session ['userSeger']; echo "bienvenue,". $ Username;..

Les étapes pour construire un système de panier d'achat efficace à l'aide de sessions comprennent: 1) Comprendre la définition et la fonction de la session. La session est un mécanisme de stockage côté serveur utilisé pour maintenir l'état de l'utilisateur entre les demandes; 2) Implémenter la gestion de session de base, comme l'ajout de produits au panier; 3) développer une utilisation avancée, soutenant la gestion de la quantité de produits et la suppression; 4) Optimiser les performances et la sécurité, en persistant les données de session et en utilisant des identifiants de session sécurisés.

L'article explique comment créer, mettre en œuvre et utiliser des interfaces dans PHP, en se concentrant sur leurs avantages pour l'organisation du code et la maintenabilité.

L'article traite des différences entre crypt () et mot de passe_hash () dans PHP pour le hachage de mot de passe, en se concentrant sur leur implémentation, leur sécurité et leur aptitude aux applications Web modernes.

L'article discute de la prévention des scripts inter-sites (XSS) dans PHP par validation d'entrée, en codage de sortie et en utilisant des outils comme OWASP ESAPI et Purificateur HTML.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Dreamweaver CS6
Outils de développement Web visuel

mPDF
mPDF est une bibliothèque PHP qui peut générer des fichiers PDF à partir de HTML encodé en UTF-8. L'auteur original, Ian Back, a écrit mPDF pour générer des fichiers PDF « à la volée » depuis son site Web et gérer différentes langues. Il est plus lent et produit des fichiers plus volumineux lors de l'utilisation de polices Unicode que les scripts originaux comme HTML2FPDF, mais prend en charge les styles CSS, etc. et présente de nombreuses améliorations. Prend en charge presque toutes les langues, y compris RTL (arabe et hébreu) et CJK (chinois, japonais et coréen). Prend en charge les éléments imbriqués au niveau du bloc (tels que P, DIV),

Adaptateur de serveur SAP NetWeaver pour Eclipse
Intégrez Eclipse au serveur d'applications SAP NetWeaver.

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

MinGW - GNU minimaliste pour Windows
Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.
