Sommaire
Gestion des arguments
Compter le nombre d'arguments
Lecture des arguments
L'ancienne technique de lecture des arguments (obsolète)
Cas des nombres variables de paramètres et des arguments optionnels
Accéder aux arguments
Cas des arguments passés par référence
Assurer la protection en écriture des autres paramètres
|
7.10.6 Cas des arguments passés par référence
Si votre fonction accepte des arguments passés par référence,
que vous souhaitez modifier, vous devez prendre certaines précautions.
Ce que nous n'avons toujours pas précisé, et que dans les circonstances
actuelles, vous n'avez pas le droit de modifier les enveloppe
zval désignant les paramètres passés à votre fonction.
Bien sûr, vous pouvez modifier n'importe quelle enveloppe
zval que vous créez dans votre fonction, mais vous
ne devez changer aucune zval qui fasse référence
aux données internes de Zend.
Nous avons uniquement parlé des fonctions *_ex,
jusqu'à maintenant. Nous avez peut être remarqué que les fonctions
que nous avons utilisé s'appelait
zend_get_parameters_ex au lieu de
zend_get_parameters,
convert_to_long_ex au lieu de
convert_to_long, etc... Les fonctions
*_ex forment les nouvelles API "étendues"
de Zend. Elles apportent une légère amélioration en terme de
vitesse sur la version précédente, mais, en échange, ne sont
conçues que pour fournir des accès en lecture seule.
Comme Zend fonctionne en interne avec des références, les
différentes variables peuvent faire référence à la même
valeur. L'accès en écriture à une enveloppe zval
impose que l'enveloppe contiennent une valeur isolée, c'est à dire
qu'elle ne doit pas être référencés par une autre enveloppe.
Si une enveloppe zval était référencée par une autre
envelope, si vous modifiez la valeur de la première, vous modifiez
aussi celle de la seconde (car elles pointent simplement vers la
valeur modifiée, et par conséquent, modifie leur propre valeur
en même temps).
zend_get_parameters_ex ne prend pas en compte
cette situation, mais retourne simplement un pointeur sur l'enveloppe
désirée, que cette dernière soit une référence ou pas.
Sa version dans l'API traditionnelle zend_get_parameters,
vérifie immédiatement les valeurs référencées. Si elle trouve une
référence, elle crée une nouvelle enveloppe zval isolée;
copie les données référencées dans le nouvel espace créé; puis retourne un
pointeur sur cette nouvelle valeur isolée.
Cette action est appelée séparation de zval
(zval separation , ou encore pval separation).
Parceque les API *_ex n'effectue pas de
séparation de zval, elle est considérablement plus rapide, mais
n'autorise pas l'accès en écriture.
Pour modifier des paramètres, un accès en écriture est nécessaire.
Zend traite cette situation d'une manière spéaciale : A chaque fois qu'un
paramètre est passé à une fonction, et qu'il est passé par référence,
Zend effectue une séparation de zval. Cela signifie que toutes les fois où
vous appelér une fonction en PHP, en passant des arguments par référence,
Zend s'assure automatiquement que $parameter est passé comme une
valeur isolée, avec la possibilité d'y accéder en écriture.
my_function(&$parameter);
Mais ce n'est pas le cas avec les paramètres
normaux. Tous les paramètres qui ne sont pas passés par références
sont dans un état de lecture seule.
Cela vous impose de devoir vous assurer que vous travaillez avec
une référence : sinon, vous risquez de produire des résultats
indésirables. Pour vérifier si un paramètre est passé par référence,
vous pouvez utiliser la macro PZVAL_IS_REF. Cette
macro accepte un valeur de type zval*,
et vérifie si c'est une référence. Des exemples sont disponibles dans
<>.
Test pour savoir si un paramètre est passé par référence |
zval *parameter; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) return; /* vérifie si le paramètre est passé par référence */ if (!PZVAL_IS_REF(*parameter)) { { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } /* modifie le paramètre */ ZVAL_LONG(*parameter, 10);
|
|