8.11 Duplique le contenu d'une variable : le bâtisseur de copie.
A un moment ou à un autre, vous aurez besoni d'assigner le contenu
d'une enveloppe
zval
à une autre. C'est plus facile
à dire qu'à faire, car une enveloppe
zval
ne contient
pas que le d'informations, mais aussi des références dans les rouages
internes du moteur Zend. Par exemple, suivant leur taille, les tableaux
et objets pourraient être imbriqués de manière complexe. En assignant
une enveloppe
zval
à une autre, vous éviter la duplication
de la table d'entrées, en utilisant simplement une référence.
Pour copier ce type de données complexes, utilisez le
bâtisseur de copie
. Les bâtisseurs de copie sont
typiquement définit dans les langages qui supportent le surchargement
d'opérateur, avec l'objectif précis de copier les objets complexes. Si
vous définissez un objet dans un tel langage, vous avez la possibilité
de surcharger l'opérateur "=", qui est généralement responsable de l'assignation
de lvalue (résultat d'une évaluation, à gauche de l'opérateur) à la
rvalue (la même chose, de l'autre coté).
Surcharger
signifie assigner un nouveau sens à
cet opérateur, et il sert généralement à impliquer un appel de fonction
lors de l'assignation. A chaque fois que cet opérateur est utilisé sur
un tel objet dans un programme, cette fonction sera appelée avec la
lvalue et la rvalue comme paramètre. Connaissant ces informations,
cette fonction peut réaliser l'opération convenue avec un "="
(C'est généralement une copie complexe).
C'est la même forme de copie complexe qui est nécessaire pour les
enveloppes
zval
de PHP. Encore une fois, dans le
cas d'un tableau, la copie complexe impliquerait la re-création de
toutes les tables de hashage liées à ce tableau. Pour les chaînes
de caractères, l'allocation de mémoire diot être assurée, etc...
Zend dispose d'une telle fonction appelée
zend_copy_ctor
(son équivalent précédent en
PHP était la fonction
pval_copy_constructor
).
Une démonstration plus pratique est la fonction qui accepte un type
complexe, le modifie et le retourne comme argument :
zval *parameter; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) return; } // faire quelques modifications au paramètre ici
// maintenant, nous voulons retourner une copie de l'enveloppe *return_value == *parameter; zval_copy_ctor(return_value);
La première partie de la fonction est un cas typique de récupération
d'arguments. Après les modifications (laissés à votre bon plaisir),
la partie interessante commence. L'enveloppe
parameter
est
assignée à l'enveloppe prédéfinie
return_value
. Maintenant,
afin de pouvoir réellement dupliquer son contenu, le bâtisseur de
copie est appelé. Il travaille directement avec l'argument fournit, et
la valeur de retour standard de cette fonction est
FAILURE
en cas d'échec, et
SUCCESS
en cas de succès.
Si vous omettez l'appel au bâtisseur de copie dans cet exemple,
les deux enveloppes
parameter
et
return_value
pointeront sur les mêmes données internes, ce qui signifie que
l'enveloppe
return_value
serait une référence illégale
vers les mêmes données. A chaque fois que des modifications auraient lieu
dans les données référencées par
parameter
,
return_value
serait aussi affecté. Ainsi, pour créer des
copies séparées, le bâtisseur de copie doit être appelé.
Le complémentaire du bâtisseur de copie de l'API Zend est le destructeur
de valeur,
zval_dtor
, qui fait le contraire du
bâtisseur.
|