8.10.1 Présentation
Pour créer de nouvelles variables qui seront accessibles hors de
vos fonctions, et utilisées par le script, vous devez allouer
une enveloppe
zval
, lui assigner une valeur significative,
et introduire la variable dans les tables internes de symboles de Zend.
Ce processu est commun à toutes les créations de variables :
zval *new_variable;
/* Alloue et initialise la nouvelle enveloppe */ MAKE_STD_ZVAL(new_variable);
/* Choisit le type et le contenu le la variable : reportez vous aux sections suivantes */
/* Introduit cette variable sous le nom de "new_variable_name" dans la table des symboles */ ZEND_SET_SYMBOL(EG(active_symbol_table), "new_variable_name", new_variable);
/* La variable est désormais accessible au script, sous le nom de $new_variable_name */
La macro
MAKE_STD_ZVAL
alloue une nouvelle enveloppe
zval
en utilisant la macro
ALLOC_ZVAL
puis, initialise cette variable avec la macro
INIT_ZVAL
.
Comme implémenté dans Zend au moment de l'écriture de ce chapitre,
initialisation
signifie configurer le compteur
de références à
1
et remettre à zéro l'option
is_ref
, mais ce processus pourra être amélioré plus tard.
C'est pour cela que c'est une bonne idée que d'utiliser la macro
MAKE_STD_ZVAL
plutôt que
ALLOC_ZVAL
.
Si vous voulez optimiser la vitesse de votre extension (et que vous
n'avez pas à initialiser explicitement votre enveloppe
zval
ici), vous pouvez utiliser
ALLOC_ZVAL
, mais ce n'est pas
recommmandé, car cette méthode n'assure pas l'intégrité de vos données.
ZEND_SET_SYMBOL
prend ne charge l'introduction de
votre variable dans la table des symboles de Zend. Cette macro vérifie
si une variable de même nom n'existe pas déjà, puis convertit la nouvelle
variable en une référence si c'est le cas (avec désallocation automatique
de l'ancienne enveloppe
zval
). C'est la meilleure méthode
si la vitesse n'est pas cruciale, et que vous souhaitez garder un niveau
d'utilisation de la mémoire bas.
Notez que
ZEND_SET_SYMBOL
fait usage des variables
globales d'exécutions via la macro
EG
. En spécifiant
EG(active_symbol_table)
, vous gagnez l'accès à
la table des symboles actives, qui gère l'environnement local. L'environnement
local peut varier de fonction en fonction.
Si vous devez optimiser la vitesse de votre extension, et que vous ne vous souciez
par de l'utilisation optimale de la mémoire, vous pouvez omettre la vérification
d'existence d'une variable ayant la même valeur, et forcer l'introduction du
symbole dans la table, en utilisant la fonction
zend_hash_update
:
zval *new_variable;
/* Alloue et initialise la nouvelle enveloppe */ MAKE_STD_ZVAL(new_variable);
/* Choisit le type et le contenu le la variable : reportez vous aux sections suivantes */
/* Introduit cette variable sous le nom de "new_variable_name" dans la table des symboles */ zend_hash_update( EG(active_symbol_table), "new_variable_name", strlen("new_variable_name") + 1, &new_variable, sizeof(zval *), NULL );
C'est la méthode qui est utilisée dans la plus part des modules.
Les variables générées avec le code ci-dessus seront placées dans l'environnement
d'exécution local : elles résident dans l'environnement de la fonction qui les
a appelées. Pour créer des variables dans l'environnement global, utilisez la même
méthode, mais faites références à une autre table de symboles :
zval *new_variable; /* Alloue et initialise la nouvelle enveloppe */ MAKE_STD_ZVAL(new_variable);
/* Choisit le type et le contenu le la variable : reportez vous aux sections suivantes */
/* Introduit cette variable sous le nom de "new_variable_name" dans la table des symboles globale */ ZEND_SET_SYMBOL(&EG(symbol_table), "new_variable_name", new_variable);
La macro
ZEND_SET_SYMBOL
est ici appelée avec une
référence sur la table des symboles globales, en utilisant la macro
EG(symbol_table)
.
Note :
La variable
active_symbol_table
est un pointeur, mais
symbol_table
n'en est pas un.
C'est pour cela que vous devez utiliser
EG(active_symbol_table)
et
&EG(symbol_table)
comme paramètre de
ZEND_SET_SYMBOL
: elle requiert un pointeur.
Similairement, pour améliorer l'efficacité de votre code, vous pouvez
coder en dur la modification de la table des symboles globale :
zval *new_variable;
/* Alloue et initialise la nouvelle enveloppe */ MAKE_STD_ZVAL(new_variable);
/* Choisit le type et le contenu le la variable : reportez vous aux sections suivantes */
/* Introduit cette variable sous le nom de "new_variable_name" dans la table des symboles globale */ zend_hash_update( &EG(symbol_table), "new_variable_name", strlen("new_variable_name") + 1, &new_variable, sizeof(zval *), NULL );
Création de variables dans différents environnements montre un exemple de sources qui
crée deux variables :
local_variable
dans l'environnement
local, et
global_variable
dans l'environnement global
(voir Figure 9.7).
Note: Vous pouvez remarquer que la variable globale n'est pas réellement accessible
depuis la fonction. C'est parcequ'elle n'est pas importée dans l'environnement
local avec
global $global_variable;
, dans le source PHP.
|