Cet article présente principalement le principe OpCode de PHP et analyse plus en détail le mécanisme de compilation pertinent et le principe de fonctionnement du programme PHP. Les amis dans le besoin peuvent s'y référer
OpCode est un script PHP compilé intermédiaire. langage, comme le ByteCode de Java ou le MSL de .NET. Cet article est principalement basé sur « Comprendre l'OPcode » et Internet. Il est enregistré sur la base d'une compréhension et d'une modification personnelles :
Code PHP :
<?php
echo "Hello World";
$a = 1 + 1;
echo $a;
?>
Copier après la connexion
<🎜. >
PHP passera par les 4 étapes suivantes lors de l'exécution de ce code :
1. Scanning (Lexing), convertir le code PHP en fragments de langage (Tokens)
2. Jetons en expressions simples et significatives
3. Compilation, compilez l'expression en Opocdes
4, exécutez les Opcodes séquentiellement, un à la fois, réalisant ainsi la fonction de script PHP.
Remarque : certains caches actuels, comme APC, peuvent permettre à PHP de mettre en cache les Opcodes. De cette façon, chaque fois qu'une requête arrive, il n'est pas nécessaire de répéter les trois premières étapes, ce qui peut grandement améliorer l'exécution. vitesse de PHP.
Tout d'abord, Zend/zend_lingual_scanner.c effectuera une analyse lexicale sur le code PHP d'entrée basé sur Zend/zend_lingual_scanner.l (fichier Lex) pour obtenir les "mots" un par un. PHP4.2+ commence à fournir A. une fonction appelée token_get_all est créée. Cette fonction peut scanner un morceau de code PHP en jetons
Copier après la connexion
obtiendra les résultats suivants :
Array
(
[0] => Array
(
[0] => 367
[1] => <?php
[2] => 1
)
[1] => Array
(
[0] => 370
[1] =>
[2] => 2
)
[2] => Array
(
[0] => 316
[1] => echo
[2] => 2
)
[3] => Array
(
[0] => 370
[1] =>
[2] => 2
)
[4] => Array
(
[0] => 315
[1] => "Hello World"
[2] => 2
)
[5] => ;
[6] => Array
(
[0] => 370
[1] =>
[2] => 2
)
[7] => Array
(
[0] => 309
[1] => $a
[2] => 3
)
[8] => Array
(
[0] => 370
[1] =>
[2] => 3
)
[9] => =
[10] => Array
(
[0] => 370
[1] =>
[2] => 3
)
[11] => Array
(
[0] => 305
[1] => 1
[2] => 3
)
[12] => Array
(
[0] => 370
[1] =>
[2] => 3
)
[13] => +
[14] => Array
(
[0] => 370
[1] =>
[2] => 3
)
[15] => Array
(
[0] => 305
[1] => 1
[2] => 3
)
[16] => ;
[17] => Array
(
[0] => 370
[1] =>
[2] => 3
)
[18] => Array
(
[0] => 316
[1] => echo
[2] => 4
)
[19] => Array
(
[0] => 370
[1] =>
[2] => 4
)
[20] => Array
(
[0] => 309
[1] => $a
[2] => 4
)
[21] => ;
[22] => Array
(
[0] => 370
[1] =>
[2] => 4
)
[23] => Array
(
[0] => 369
[1] => ?>
[2] => 5
)
)
Copier après la connexion
Le résultat renvoyé, les chaînes, les caractères et les espaces dans le code source seront renvoyés inchangés. Les caractères de chaque code source apparaîtront dans l'ordre correspondant. Cependant, d'autres éléments tels que les balises, les opérateurs et les instructions seront convertis en un tableau contenant deux parties : l'ID du jeton (c'est-à-dire le code correspondant pour changer le jeton dans Zend, tel que T_ECHO, T_STRING) et le code original dans Zend. le contenu du code source.
L'étape suivante est l'étape d'analyse. L'analyse supprimera d'abord les espaces excédentaires dans le tableau de jetons, puis convertira les jetons restants en expressions simples un par un
1.
2. ajoutez deux nombres ensemble
3. stockez le résultat de l'expression précédente dans une variable
4. faites écho à une variable
Ensuite, changez l'étape de compilation, les jetons seront compilés. dans les op_arrays un par un. Chaque op_arrayd contient les 5 parties suivantes :
1 L'identification du numéro d'Opcode indique le type d'opération de chaque op_array, tel que add, echo
2. result
3. L'opérande 1 est l'opérande de l'Opcode
4. Opérande 2
5. La valeur étendue est un entier utilisé pour distinguer l'opérateur surchargé
Par exemple, le code PHP le fera. être analysé en :
[root@localhost html]# /usr/local/php/bin/php -dvld.active=1 hello.php
Branch analysis from position: 0
Return found
filename: /var/www/html/hello.php
function name: (null)
number of ops: 6
compiled vars: !0 = $a
line # op fetch ext return operands
-------------------------------------------------------------------------------
2 0 ECHO 'Hello+world'
3 1 ADD ~0 1, 1
2 ASSIGN !0, ~0
4 3 ECHO !0
6 4 RETURN 1
5* ZEND_HANDLE_EXCEPTION
Hello world2
Copier après la connexion
Chaque opérande est composé des deux parties suivantes :
a) op_type : IS_CONST, IS_TMP_VAR, IS_VAR , IS_UNUSED, ou IS_CV
b) u, une union, qui stocke la valeur (const) ou la lvalue de l'opérande dans différents types en fonction de l'op_type (var)
Pour var, chaque variable est différente. IS_TMP_VAR, comme son nom l'indique, il s'agit d'une variable temporaire qui enregistre certains résultats de op_array pour une utilisation dans le prochain op_array. Le u de ce type d'opérande stocke un handle (entier) pointant vers la table de variables. utilisé~ Le début, tel que ~0, représente la variable temporaire inconnue IS_VAR au numéro 0 dans la table des variables. Il s'agit de notre variable générale. Ils commencent par $ pour représenter IS_CV, qui représente le type utilisé par les compilateurs après ZE2.1/. Mécanisme de cache PHP5.1, cette variable stocke l'adresse de la variable référencée par elle lorsqu'une variable est référencée pour la première fois, les références ultérieures à cette variable n'ont pas besoin de rechercher à nouveau la table des symboles active. . Les variables CV sont représentées en commençant par !.
La variable $a est optimisée à !0.
Résumé : Ce qui précède représente l'intégralité du contenu de cet article, j'espère qu'il sera utile à l'étude de chacun.
Recommandations associées :
Méthode d'utilisation du verrouillage pour implémenter la fonction de capture de code sous concurrence basée sur PHP
Chargement automatique PHP Méthode d'implémentation simple
Comparaison du temps d'exécution de quatre algorithmes de tri de base implémentés en PHP (à lire absolument)
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!