La colonne
Nous savons tous que les variables PHP sont faiblement typées, et il n'est pas nécessaire de spécifier le type lors de leur déclaration. Alors, comment cela est-il mis en œuvre ? Cela doit commencer par la structure de base des variables.
Dans le fichier de code source zend_type.h, vous pouvez voir la définition de zval :
typedef struct _zval_struct zval;struct _zval_struct { zend_value value; /* value */ union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } v; uint32_t type_info; } u1; union { uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ uint32_t access_flags; /* class constant access flags */ uint32_t property_guard; /* single property guard */ uint32_t extra; /* not further specified */ } u2; }复制代码
La structure de zval est constituée d'une valeur ou d'un pointeur qui contient le type de variable L'union zend_value et les deux unions u1 et u2 forment
u1 est utilisé pour enregistrer le type de variable et ses informations, ainsi que les champs à l'intérieur it Les utilisations sont les suivantes :
type : type de variable d'enregistrement. Vous pouvez accéder à
type_flags via u2.v.type: balises correspondant aux types uniques de variables (tels que les types constants, les types de comptage de références, les types immuables correspondent à différents indicateurs).
const_flags : drapeaux de type constant
reserved : champs réservés
u2 est principalement une fonction auxiliaire, en raison de la structure La mémoire est alignée, donc l'espace de u2 a déjà occupé de l'espace avec ou sans u2, donc il est utilisé. Le champ auxiliaire de u2 enregistre de nombreuses informations de type, ce qui est très bénéfique pour les fonctions internes, ou améliore la convivialité du cache ou réduit les opérations d'adressage mémoire. Certains de ces domaines sont présentés ici.
next : utilisé pour résoudre le problème du conflit de hachage (le conflit de hachage n'est pas encore compris) et enregistrer la position de l'élément suivant du conflit.
cache_slot : cache d'exécution. Lors de l'exécution d'une fonction, elle recherchera d'abord dans le cache. Si elle n'est pas trouvée dans le cache, elle recherchera ensuite dans la table des fonctions globales.
num_args : le nombre de paramètres transmis lorsque la fonction est appelée.
access_flags : l'indicateur d'accès de la classe d'objet, telle que public protected private.
typedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮点型 */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww; } zend_value;复制代码
Comme le montre zend__value, les types longs et doubles stockent directement les valeurs, tandis que les autres types sont des pointeurs, pointant vers leurs structures respectives. Par conséquent, en raison de structures comme zval, les variables PHP n'ont pas besoin de spécifier explicitement leurs types lors de leur déclaration, car quel que soit le type de valeur que vous attribuez à la variable, cela peut vous aider à trouver la structure de stockage correspondante.
En prenant comme exemple une variable dont la valeur est une chaîne, sa structure est la suivante :
Vous pouvez constater que le zval de php7 n'occupe que 16 octets au total, ce qui permet d'économiser beaucoup de mémoire par rapport aux 48 octets de zval de PHP5.
De plus, en PHP5, toutes les variables sont allouées dans le tas, mais pour les variables temporaires, il n'est pas nécessaire d'allouer dans le tas. Par conséquent, cela a été optimisé en PHP7 et les variables temporaires sont appliquées directement sur la pile.
Ce qui suit présente plusieurs types courants de structures de variables. Pour d'autres types, vous pouvez vérifier vous-même le code source.
Pour les types entiers et virgule flottante, en raison de leur petit espace, les valeurs entièressont directement stockées dans zval et sont stockées dans le type lval. la valeur est stockée dans dval.
typedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮点型 */ ... }复制代码
Une nouvelle structure de chaîne est définie dans PHP 7. La structure est la suivante :
struct _zend_string { zend_refcounted_h ; zend_ulong h; /* hash value */ size_t len; char val[1]; };复制代码
La signification de chaque champ ci-dessus :
gc : Informations de référence variable, tous les types de variables qui utilisent le comptage de références auront cette structure.
h : valeur de hachage, utilisée lors du calcul de l'index dans un tableau. (On dit que cette opération améliore les performances de PHP7 de 5%)
len : Longueur de chaîne, la sécurité binaire est assurée grâce à cette valeur
val : Contenu de chaîne, structure de longueur variable, appuyez sur lorsque la longueur de lentille allouée s'applique à la mémoire Array
array est une structure de données très puissante en PHP. Son implémentation sous-jacente est une HashTable ordonnée ordinaire. Voici un bref aperçu de sa structure. Plus de détails seront donnés plus tard.
typedef struct _zend_array HashTable;struct _zend_array { zend_refcounted_h gc; union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar flags, zend_uchar nApplyCount, zend_uchar nIteratorsCount, zend_uchar consistency) } v; uint32_t flags; } u; uint32_t nTableMask; Bucket *arData; uint32_t nNumUsed; uint32_t nNumOfElements; uint32_t nTableSize; uint32_t nInternalPointer; zend_long nNextFreeElement; dtor_func_t pDestructor; }复制代码
###Object
La structure des objets de PHP7 a également été repensée, ce qui est très différent de l'implémentation de PHP5.
struct _zend_object { zend_refcounted_h gc; uint32_t handle; zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; zval properties_table[1]; };复制代码
Voici quelques-uns des champs :
gc : en-tête gc
*ce : classe correspondant à la classe d'objet
*propriétés : Structure HashTable , key est le nom de l'attribut de l'objet, value est le décalage de la valeur de l'attribut dans le tableau Properties_tables et la valeur de l'attribut correspondante se trouve dans Properties_talbe via le décalage.
properties_talbe[1] : stocke la valeur d'attribut de l'objet
Recommandation gratuite : PHP7
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!