Maison > développement back-end > tutoriel php > Compréhension approfondie de la référence du noyau PHP7

Compréhension approfondie de la référence du noyau PHP7

藏色散人
Libérer: 2023-04-05 07:42:01
avant
2299 Les gens l'ont consulté

J'ai mentionné auparavant que la référence (REFERENCE) était un indicateur en PHP5, et après PHP7, nous l'avons transformé en un nouveau type : IS_REFERNCE. Cependant, la référence est une application très courante, donc ce changement a apporté beaucoup de changements, et a également provoqué de nombreux bugs lors du développement de PHP7 car nous avons parfois négligé de gérer ce type.

Compréhension approfondie de la référence du noyau PHP7

Le cas le plus simple est celui de gérer différents types désormais. pour considérer davantage ce nouveau type. Par exemple, en PHP7, cette forme de code est devenue très courante :

try_again:
swtich (Z_TYPE_P(zv)) {
     case IS_TRING:
     break;
     case IS_ARRAY:
     break;
    ...
     case IS_REFERENCE:
     zv = Z_REFVAL_P(zv); //解引用
     goto try_again;
     break;
}
Copier après la connexion

Si vous écrivez vos propres extensions et oubliez de considérer ce nouveau type, cela posera des problèmes.

Pourquoi ?

Donc, puisque ce nouveau type, les types posent tant de problèmes, pourquoi avons-nous changé la référence en type ? Pourquoi ne pas simplement utiliser un indicateur ?<🎜 ? >

En un mot, nous devons faire cela. - _#

Comme mentionné précédemment, Hashtable stocke directement zval, donc dans la table des symboles, comment deux zval peuvent-ils partager une valeur pour des types complexes tels ? comme chaînes, il semble que nous puissions utiliser zend_refcounted. Un bit d'indicateur est ajouté à la structure pour indiquer qu'il est résolu par référence. Cependant, cela rencontrera également une copie provoquée par Change On Write, mais nous savons qu'en PHP7, certains types le sont. directement stocké dans zval, comme IS_LONG, mais les types de référence Le comptage de références est requis, alors comment représenter un zval qui est IS_LONG et IS_REFERNCE ?

Pour cette raison, nous avons créé ce nouveau type :

Compréhension approfondie de la référence du noyau PHP7

Comme le montre la figure, reference est un nouveau type : zend_reference pour zval de type IS_REFERNCE, zval.value.ref est un pointeur vers zend_reference, qui contient un nombre de références et un zval, le zval spécifique La valeur est stockée dans zval.value.ref->val

Donc pour la référence de IS_LONG, utilisez un zval de type IS_REFERNCE, qui pointe vers un zend_reference, et ce zend_reference-> val est un zval de type IS_LONG.

Change On Write

PHP utilise le comptage de références pour effectuer un garbage collection simple :

<?php
1. $val = "laruence";
2. $ref = &$val;
3. $copy = $val;
?>
Copier après la connexion
$ref et $val sont des références pointant vers le même zval. En PHP5, nous avons représenté cette situation par un nombre de références de 2 et un indicateur de référence de 1. Lors de la copie de $val vers When $copy(line 3), nous a trouvé que $val est une référence avec un nombre supérieur à 1, donc un changement à l'écriture est requis, c'est-à-dire une séparation. Nous devons donc copier ce zval.

En PHP7, la situation devient beaucoup plus simple. . Premièrement, lorsque la référence est affectée à $ref (ligne 2), un type IS_REFERNCE est généré, puis comme il y a deux variables qui le référencent à ce moment, le nombre de références de la structure zend_reference est zval.value.ref- >. ;gc.refcount est 2.

Lorsque la valeur est ensuite attribuée à $copy (ligne 3), il s'avère que $val est une référence, donc $copy pointe vers zval.value.ref-> val, c'est-à-dire le zval dont la valeur de chaîne est laruence, puis augmentez le nombre de références de zval de 1, c'est-à-dire que zval.value.ref->val.value.str.gc.refcount est 2. Aucune copie n'a lieu .

Cela résout efficacement le problème classique de PHP5 évoqué dans le chapitre précédent. Par exemple, lorsqu'on lance le problème du chapitre précédent sous PHP7, le résultat que l'on obtient est :

<🎜. >On peut voir qu'aucune copie ne se produit, il n'y aura donc aucun problème de performances.
$ php-7.0/sapi/cli/php /tmp/1.php
Used 0.00021380008539
Used 0.00020173048281
Copier après la connexion

Recommandé : "

Tutoriel PHP

"

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!

Étiquettes associées:
source:laruence.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal