8.9 Gestion des arguments
8 Développer PHP 4.0
Manuel PHP
. Déterminer le nombre d'arguments ->Lire les arguments . Ancienen méthode de lecture des arguments (obsolète) . Traitement des nombres d'arguments variables et des paramètres optionnels . Accéder aux arguments . Traiter les arguments passés par référence . Assurer les autres paramètres contre l'écriture
|
8.9.2 Lire les arguments
Note | Nouvelle API d'analyse des paramètres
Ce chapitre document la nouvelle API d'analyse des paramètres
du moteur Zend, introduite par Andrei Zmievski. Elle a été introduite
en développement entre PHP 4.0.6 et 4.1.0 .
|
Analyser les paramètres est une tâche très commune et qui devient
laborieuse. Il serait aussi bien de disposer d'un système de
validation standardisé, et des messages d'erreurs commun. Depuis
PHP 4.1.0, il existe une nouvelle API qui comble ce manque. Elle
simplifie grandement le processus de reception des paramètres, mais
elle ne peut être utilisée pour des fonctions qui acceptent
un nombre variable d'arguments. Mais comme la vaste majorité des
fonctions a un nombre d'arguments fixe, cette API est recommandée
comme nouveau standard.
Le prototype de la fonction d'analyse des paramètres ressemble a ceci :
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
Le premier argument de cette fonction est le nombre réel de
paramètres de votre fonction, et la macro
ZEND_NUM_ARGS()
pourra être utilisée pour cela. Le deuxième paramètre
doit toujours être la macro
TSRMLS_CC
. Le troisième
argument est une chaine qui spécifie le nombre et le type des arguments
attendus par votre fonction, dans un format qui est proche de celui
utiliés par printf. Et finalement, le reste des arguments sont des
pointeurs vers les variables qui recevront les valeurs de ces paramètres.
zend_parse_parameters
effectue des conversions
de type lorsque c'est possible, ce qui fait que vous devriez recevoir
les données dans le format que vous avez demandé. Tous les types de
scalaires peuvent etre convertit dans un autre type de scalaire, mais
les conversions entre les types complexes (tableaux, objets, ressources..)
et les types scalaires ne sont pas permis.
SI les paramètres ont pu être obtenu et qu'il n'y a pas eu d'erreur
durant le traitement, la fonction retourne
SUCCESS
,
et sinon
FAILURE
. La fonction affichera des messages
d'erreurs informatifs, si le nombre de paramètres ne correspond pas au
nombre attendu, ou si les conversions de types ont échoué.
Voici quelques exemples de messages d'erreurs :
Warning - ini_get_all() requires at most 1 parameter, 2 given
Warning - wddx_deserialize() expects parameter 1 to be string, array given
Bien sur, chaque message d'erreur est accompagné par le nom du fichier
et le numéro de ligne.
Voici la liste complèete des spécificateurs de type :
-
l -
long
-
d -
double
-
s -
chaîne de caractères (avec potentiellement le caractère null) et sa longueur
-
b -
booléen
-
r -
resource, stockée en
zval*
-
a -
tableau, stocké en
zval*
-
o -
objet (de n'importe quelle classe), stocké en
zval*
-
O -
objet (de la classe spécifiée par class entry), stocké en
zval*
-
z -
un
zval*
Les caractères suivantts on aussi des significations dans la chaîne de spécificateurs ;
-
| -
indique que les paramètres restants
sont optionnels. Les variables de stockage de ces paramètres
doivent être initialisées à leur valeur par défaut (définie par
l'extension) car elles seront ignorées par la fonction d'analyse
si les paramètres ne sont pas fournis.
-
/ -
la fonction d'analyse
va appeler
separate_zval_if_not_ref
sur le
paramètre suivant, pour fournir une copie du paramètre, à moins
que cela ne soit une référence.
-
! -
Le paramètre qui suit peut être
du type spécifié ou
NULL
(uniquement pour
a, o, O, r, et z). Si
NULL
est passé par l'utilisateur, le pointeur de stockage utilisera
NULL
.
La meilleure méthode pour illustrer l'utilisation de ces fonctions est de voir
un exemple :
/* Lit un long, une chaîne et sa longueur, et un zval. */ long l; char *s; int s_len; zval *param; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz", &l, &s, &s_len, ¶m) == FAILURE) { return; }
/* Lit un objet de classe spécifiée par my_ce, et un double optionnel. */ zval *obj; double d = 0.5; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d", &obj, my_ce, &d) == FAILURE) { return; }
/* Lit un objet ou null, et un tableau. Si null est passé comme objet, obj prendra la valeur NULL.*/ zval *obj; zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!a", &obj, &arr) == FAILURE) { return; }
/* Lit un tableau. */ zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &arr) == FAILURE) { return; }
/* Lit seulement les trois premiers paramètres (utile pour les fonctions à nombre d'arguments variable) */ zval *z; zend_bool b; zval *r; if (zend_parse_parameters(3, "zbr!", &z, &b, &r) == FAILURE) { return; }
Notez que dans le dernier exemple, nous utilisons 3 comme nombre d'arguments
reçus et non pas
zend_num_args
. Ce que cela
nous permet est de recevoir le nombre minimum de paramètres que
notre fonction attend. Bien sur, si vous souhaites utiliser les
autres paramètres, vous devrez utiliser la fonction
zend_get_parameters_array_ex
pour les
obtenir.
La fonction d'analyse des paramètres dispose d'une version plus puissante, qui vous
permet de passer des options qui contrôle son comportement.
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
Actuellement, la seule option utilisable est
ZEND_PARSE_PARAMS_QUIET
,
qui commande à la fonction de ne pas afficher de messages d'erreur
durant son exécution. Cela peut être utile pour des fonctions qui
attendent différents ensembles d'arguments très différents, mais, d'un
autre coté, vous devrez afficher vous même les erreurs.
Par exemple, voici commme vous pourriez attendre soit trois entiers, soit une
chaîne de caractères.
long l1, l2, l3; char *s; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lll", &l1, &l2, &l3) == SUCCESS) { /* traiter les longs */ } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s", &s, &s_len) == SUCCESS) { /* traiter la chaîne */ } else { php_error(E_WARNING, "%s() prend soit trois longs, soit une chaîne comme arguments", get_active_function_name(TSRMLS_C)); return; }
Avec toutes les méthodes sus-cités de reception des paramètres,
vous devriez avoir une bonne visibilité sur le processus. Pour d'autres
exemples, fouillez donc le code source de PHP, et les extensions qui sont
fournies avec PHP : ce sont d'excellentes illustrations.
|