Gérer les paramètres de fonction
Notre fonction tutorial_function1 ne gère pas les paramètres qu'on peut lui passer en argument. Nous allons donc gérer les paramètres dans une nouvelle fonction que nous allons créé.
Tout d'abord, dans tutorial.h ajoutez une déclaration (en dessous de la déclaration de tutorial_function1):
ZEND_FUNCTION(tutorial_function1);
ZEND_FUNCTION(tutorial_function2);
Puis allez dans tutorial.c pour créer cette nouvelle fonction.
Renseignez notre nouvelle fonction dans le registre que nous avons déclaré, c'est à dire la liste tutorial_functions:
/* La liste des fonctions que zend va rendre accessible par ce module */
static zend_function_entry tutorial_functions[] =
{
ZEND_FE(tutorial_function1, NULL)
ZEND_FE(tutorial_function2, NULL)
{NULL, NULL, NULL}
};
Maintenant, en bas du fichier tutorial.c, nous allons coder une fonction qui peut prendre des paramètres en arguments. La fonction zend_parse_parameters() va nous servir à cela.
/* prototype de la fonctione, pour comprendre... */
int zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, char* list, &val1, &val2...)
Ce qui importe, c'est l'argument list qui sera une chaine de caractères définissant la liste des paramètres. Par exemple, pour lire récupérer un long (nombre), il faudra faire:
int variable1;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &variable1);
l étant défini pour lire un long. Seule exception, les chaînes de caractères qui vont retourner la valeur et la taille:
char *variable1;
int variablelen;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &variable1, &variablelen);
Voici donc ce que vous pouvez récupérer:
| caractère | Type PHP | type |
|---|---|---|
| l | number | long |
| d | number | double |
| s | string | char*, int |
| b | bool | boolean |
| o | object | zval* |
| a | array | zval* |
| r | resource | zval* |
| z | number | zval* |
zval est une structure particulière, que nous verrons plus tard, permettant de mapper les scalaires PHP... en fait, toute variable peut être récupéré dans un zval. Voici son prototype:
struct {
union {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
} value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
zend_parse_parameters retourne un entier pour définir si oui ou non il a put lire les paramètres correctement. Plutôt que d'utiliser 1 ou 0, utilisez plutôt SUCCESS ou FAILURE.
Admettons que notre fonction veuille récupérer une chaine de caractère:
ZEND_FUNCTION(tutorial_function2)
{
char *var;
int len;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &var, &len) == FAILURE )
{
/* Erreur, nous n'avons pas eut les paramètre escomptés */
RETURN_NULL()
}
php_printf("paramètre lut: %s\n",var);
}
Compliez avec make puis (en root), make install. En tant qu'utilisateur (donc exit si vous êtes en root):
[pafer@localhost tutoext]$ php -d extension=tutorial.so -r "tutorial_function2('ok');"
paramètre lut: ok
[pafer@localhost tutoext]$
Nous pouvons aussi gérer plusieurs paramètres; par exemple:
ZEND_FUNCTION(tutorial_function2)
{
char *var;
int len;
long longval;
/* La chaine "sl" indique que nous cherchons un "long" et une chaine "string" */
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &var, &len,&longval) == FAILURE )
{
/* Erreur, nous n'avons pas eut les paramètre escomptés */
RETURN_NULL()
}
php_printf("paramètre lut: %s et %d\n",var,longval);
}
Donc après un "make" puis (en root) "make install", nous pouvons tester:
patachou@portablepatrice:~/Projets/php/tutorial$ php -d extension=tutorial.so -r "tutorial_function2('toto',55);"
paramètre lut: toto et 55
Pour rendre des paramètres optionnels, il suffit de précéder les entrées par un "pipe" ( | via ALTGR+6), puis de tester si une valeur existe, regardez l'exemple:
ZEND_FUNCTION(tutorial_function2)
{
char *var;
int len;
long longval = NULL;
/* La chaine "sl" indique que nous cherchons un "long" et une chaine "string" */
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &var, &len,&longval) == FAILURE )
{
/* Erreur, nous n'avons pas eut les paramètre escomptés */
RETURN_NULL()
}
php_printf("paramètre lut: %s\n",var);
if(longval!=NULL){
php_printf("paramètre optionnel: %d\n",longval) ;
}
}
Ce qui peut s'utiliser de cette manière:
patachou@portablepatrice:~/Projets/php/tutorial$ php -d extension=tutorial.so -r "tutorial_function2('toto');"
paramètre lut: toto
patachou@portablepatrice:~/Projets/php/tutorial$ php -d extension=tutorial.so -r "tutorial_function2('toto',63);"
paramètre lut: toto
paramètre optionnel: 63
patachou@portablepatrice:~/Projets/php/tutorial$
La suite... travailler avec les zval, créer des classes, des objets... des resources... (à suivre donc)
5 commentaire(s)


