[Traduction][Développement d'extensions php et embarqué] Chapitre 2 - L'intérieur et l'extérieur des variables
黄舟
Libérer: 2023-03-05 16:08:02
original
1375 Les gens l'ont consulté
Les tenants et les aboutissants des variables
Une fonctionnalité commune à chaque langage de programmation est le stockage et la récupération d'informations ; PHP ne fait pas exception, bien que de nombreux langages exigent que toutes les variables soient définies avant utilisation, ainsi que leurs informations de type. est corrigé, mais PHP permet aux programmeurs de créer des variables lorsqu'ils les utilisent et peut stocker des informations qui peuvent être exprimées dans n'importe quel type de langage. Il peut également convertir automatiquement les types de variables en cas de besoin.
Parce que vous avez utilisé user-. space PHP, il faut savoir que ce concept est du "typage faible". Dans ce chapitre, vous verrez cette information dans le langage parent de PHP-c (les types du C sont stricts) Comment est-il codé
Bien sûr, l'encodage des données ne représente que la moitié du travail. Pour garder une trace de toutes ces informations, chaque variable a également besoin d'une étiquette et d'un conteneur. Du point de vue de l'espace utilisateur, vous pouvez les considérer comme les concepts de noms et de portée de variables.
Type de données
L'unité de stockage des données en php est zval, également appelée Zend Value. C'est une structure avec seulement 4 membres Body, définie dans Zend/zend.h, a le format suivant :
Nous pouvons intuitivement deviner les types de stockage de base de la plupart de ces membres : refcount d'entier non signé, type et is_ref de caractère non signé. Le membre valeur est en fait une structure définie comme une union. est défini comme suit :
typedef union _zvalue_value {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
} zvalue_value;
Copier après la connexion
Union permet à Zend d'utiliser une structure unique et unifiée pour stocker de nombreux types de données différents dans une variable php
zend définit actuellement 8 types de données répertoriés. dans le tableau suivant :
tapez Valeur
Objectif
IS_NULL
Ce type est automatiquement attribué aux variables non initialisées jusqu'à sa première utilisation. Il peut également être utilisé par l'utilisateur. L'espace utilise la constante NULL intégrée pour une affectation explicite. data", qui est différent du booléen FALSE et de l'entier 0.
IS_BOOL
Les variables booléennes peuvent avoir l'un des deux états possibles, TRUE/FALSE. Utilisateur Les structures de contrôle d'espace if/while/ternary/for et d'autres expressions conditionnelles intermédiaires seront évaluées lors de l'évaluation de la conversion implicite en type booléen.
IS_DOUBLE
Type de données à virgule flottante , en utilisant le type de données double signé du système hôte, les nombres à virgule flottante ne sont pas stockés avec une précision exacte, une formule est utilisée pour représenter la précision finie de la partie décimale de la valeur (Annotation : les nombres à virgule flottante sont représentés en 3 parties. : signe, mantisse - partie fractionnaire, exposant. La valeur d'un nombre à virgule flottante = signe * mantisse * 2^exposant - --Extrait du manuel des fonctions de la bibliothèque BSD : float(3)). plage de valeurs (positives ou négatives) : 2,225*10^(-308) à 1,798 peut être représentée sur 8 octets * Un nombre compris dans la plage *10^(308). Malheureusement, la décimale réelle du nombre auquel il est évalué. n'est pas toujours stockée aussi proprement qu'une fraction binaire. Par exemple, l'expression décimale 0,5 se convertit en la valeur binaire exacte de 0,1, alors que la conversion décimale de 0,8 en binaire est une boucle infinie de 0,1100110011..., et quand c'est le cas. reconvertis en décimal, les bits binaires supprimés ne peuvent pas être récupérés car ils ne peuvent pas être stockés. De même, vous pouvez penser à convertir 1/3 en décimal 0,333333, deux La valeur est très similaire, mais elle est imprécise car 3 * 0,333333 n'est pas égal. à 1,0. Cette imprécision déroute souvent les gens lors du traitement de nombres à virgule flottante sur des ordinateurs (ces limites de plage sont généralement basées sur des plates-formes 32 bits ; les plages peuvent varier selon les systèmes)
IS_STRING
Le type de données le plus courant en PHP est la chaîne, qui est stockée de la manière attendue par les programmeurs C expérimentés. Allouez une mémoire suffisamment grande pour contenir tous les octets/caractères de la chaîne et enregistrez le pointeur sur la chaîne dans l'hôte zval.
Il est à noter que la longueur de la chaîne PHP est toujours explicitement indiquée dans la structure zval. Cela permet à la chaîne de contenir des octets NULL sans être tronquée. aspect des chaînes PHP « binaires sûres » car cela permet de contenir en toute sécurité tout type de données binaires
Il convient de noter que la quantité totale de mémoire allouée pour une chaîne PHP est toujours minimisée : la longueur plus. 1. Le dernier octet stocke le caractère NULL de fin, donc peu importe que les fonctions binaires sécurisées puissent recevoir directement des pointeurs de chaîne.
IS_ARRAY
Un tableau est une variable à usage spécial dont la seule fonction est d'organiser d'autres variables Contrairement au concept de tableau en C, le tableau de php n'est pas un vecteur de a. un seul type de données (comme zval arrayofzvals[];). En fait, le tableau de PHP est une collection complexe de buckets de données, et son intérieur est un HashTable. Chaque élément (bucket) de HashTable contient deux éléments d'information correspondants : des balises et des données. . Dans le scénario d'application du tableau PHP, la balise est la clé ou la valeur du tableau associé. La donnée est la variable (zval) pointée par la clé
IS_OBJECT<🎜. ><🎜 Les objets disposent de tableaux de stockage de données multi-éléments, en plus de l'ajout de méthodes, de modificateurs d'accès, de constantes de portée et de gestionnaires d'événements spéciaux. En tant que développeur d'extensions, c'est un grand défi de créer un code orienté objet équivalent en PHP 4. et PHP 5. Un gros défi, car il y a de très gros changements dans le modèle objet interne entre Zend Engine 1 (php4) et Zend Engine 2 (php5).
IS_RESOURCE
Certains types de données ne peuvent pas être simplement mappés à l'espace utilisateur. Par exemple, le pointeur FILE de stdio ou le handle de connexion de libmysqlclient, ils ne peuvent pas être simplement mappés à un tableau de valeurs scalaires, sinon ils perdront leur signification. protéger les utilisateurs Les rédacteurs de scripts spatiaux n'ont pas à gérer ces problèmes. PHP fournit un type de données de ressources pan-chinois. Nous aborderons les détails d'implémentation des types de ressources dans le chapitre 9 « Types de données de ressources ». c'est une telle chose.
void describe_zval(zval *foo)
{
if (foo->type == IS_NULL) {
php_printf("The variable is NULL");
} else {
php_printf("The variable is of type %d", foo->type);
}
}
void describe_zval(zval *foo)
{
if (Z_TYPE_P(foo) == IS_NULL) {
php_printf("The variable is NULL");
} else {
php_printf("The variable is of type %d",
Z_TYPE_P(foo));
}
}
void display_values(zval boolzv, zval *longpzv,
zval **doubleppzv)
{
if (Z_TYPE(boolzv) == IS_BOOL) {
php_printf("The value of the boolean is: %s\n",
Z_BVAL(boolzv) ? "true" : "false");
}
if (Z_TYPE_P(longpzv) == IS_LONG) {
php_printf("The value of the long is: %ld\n",
Z_LVAL_P(longpzv));
}
if (Z_TYPE_PP(doubleppzv) == IS_DOUBLE) {
php_printf("The value of the double is: %f\n",
Z_DVAL_PP(doubleppzv));
}
}
{
zval **fooval;
if (zend_hash_find(EG(active_symbol_table),
"foo", sizeof("foo"),
(void**)&fooval) == SUCCESS) {
php_printf("Got the value of $foo!");
} else {
php_printf("$foo is not defined.");
}
}
void display_zval(zval *value)
{
switch (Z_TYPE_P(value)) {
case IS_NULL:
/* NULLs are echoed as nothing */
break;
case IS_BOOL:
if (Z_BVAL_P(value)) {
php_printf("1");
}
break;
case IS_LONG:
php_printf("%ld", Z_LVAL_P(value));
break;
case IS_DOUBLE:
php_printf("%f", Z_DVAL_P(value));
break;
case IS_STRING:
PHPWRITE(Z_STRVAL_P(value), Z_STRLEN_P(value));
break;
case IS_RESOURCE:
php_printf("Resource #%ld", Z_RESVAL_P(value));
break;
case IS_ARRAY:
php_printf("Array");
break;
case IS_OBJECT:
php_printf("Object");
break;
default:
/* Should never happen in practice,
* but it's dangerous to make assumptions
*/
php_printf("Unknown");
break;
}
}
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