Maison  >  Article  >  développement back-end  >  Compréhension approfondie du passage de paramètres des fonctions personnalisées PHP

Compréhension approfondie du passage de paramètres des fonctions personnalisées PHP

伊谢尔伦
伊谢尔伦original
2017-06-26 13:29:151532parcourir

Paramètres de la fonction

La définition d'une fonction est simplement un processus d'enregistrement du nom de la fonction dans la liste des fonctions.

1. Paramètres de la fonction personnalisée

Nous savons que la vérification des paramètres de la fonction est implémentée via la fonction zend_do_receive_arg Dans cette fonction, le code clé du. Les paramètres sont les suivants :

CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info,
        sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
cur_arg_info->name = estrndup(varname->u.constant.value.str.val,
        varname->u.constant.value.str.len);
cur_arg_info->name_len = varname->u.constant.value.str.len;
cur_arg_info->array_type_hint = 0;
cur_arg_info->allow_null = 1;
cur_arg_info->pass_by_reference = pass_by_reference;
cur_arg_info->class_name = NULL;
cur_arg_info->class_name_len = 0;
L'ensemble du transfert des paramètres est complété par l'attribution de valeurs au champ arg_info du code intermédiaire. Le point clé est dans le champ arg_info. La structure du champ arg_info est la suivante :

typedef struct _zend_arg_info {
    const char *name;   /*参数的名称*/
    zend_uint name_len;     /*参数名称的长度*/
    const char *class_name; /* 类名*/
     zend_uint class_name_len;   /*类名长度*/
    zend_bool array_type_hint;  /*数组类型提示*/
    zend_bool allow_null;   /*是否允许为NULLͺ*/
    zend_bool pass_by_reference;    /*是否引用传递*/
    zend_bool return_reference; 
    int required_num_args;  
} zend_arg_info;
La différence entre le passage de la valeur du paramètre et le passage du paramètre est obtenue via le paramètre pass_by_reference lors de la génération du code intermédiaire.

Concernant le nombre de paramètres, le champ arg_nums contenu dans le code intermédiaire sera augmenté de 1 à chaque fois que **zend_do_receive_argxx est exécuté. Le code suivant :

CG(active_op_array)->num_args++;
Et l'index de. le paramètre actuel est CG(active_op_array)->num_args-1. Le code suivant :

cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
L'analyse ci-dessus concerne les paramètres lorsque la fonction est définie, et ces paramètres sont fixes. Lors de l'écriture d'un programme, nous pouvons utiliser des

paramètres variables . Nous utiliserons actuellement les fonctions func_num_args et func_get_args. Elles existent en tant que fonctions internes. Retrouvez donc l'implémentation de ces deux fonctions dans le fichier Zendzend_builtin_functions.c. Regardons d'abord l'implémentation de la fonction func_num_args. Le code est le suivant :

/* {{{ proto int func_num_args(void)
   Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)
{
    zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
 
    if (ex && ex->function_state.arguments) {
        RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
    } else {
        zend_error(E_WARNING,
"func_num_args():  Called from the global scope - no function context");
        RETURN_LONG(-1);
    }
}
/* }}} */
Lorsque ex->function_state.arguments existe et lorsque la fonction est appelée, ex->function_state.arguments est. renvoyé après la valeur de conversion, sinon une erreur est affichée et -1 est renvoyé. Le point le plus critique ici est EG (current_execute_data). Cette variable stocke les données du programme ou de la fonction en cours d'exécution. À ce stade, nous devons obtenir les données du programme en cours d'exécution précédent. Pourquoi ? Parce que l'appel de cette fonction est exécuté après la saisie de la fonction. Les données pertinentes de la fonction sont toutes dans le processus d'exécution précédent, donc l'appel est :

zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
2. Paramètres de la fonction interne

En prenant la fonction de comptage commune comme exemple, sa partie traitement des paramètres Le code est le suivant :

/* {{{ proto int count(mixed var [, int mode])
   Count the number of elements in a variable (usually an array) */
PHP_FUNCTION(count)
{
    zval *array;
    long mode = COUNT_NORMAL;
 
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l",
         &array, &mode) == FAILURE) {
        return;
    }
    ... //省略
}
Cela comprend deux opérations : l'une consiste à obtenir le nombre de paramètres et l'autre à analyser la liste des paramètres.

(1) Obtenir le nombre de paramètres

Obtenir le nombre de paramètres est obtenu grâce à la macro ZEND_NUM_ARGS(), qui est définie comme suit :

#define ZEND_NUM_ARGS()     (ht)
ht est ht dans la macro INTERNAL_FUNCTION_PARAMETERS définie dans le fichier Zend/zend.h, comme suit

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value,
zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
(2) Liste des paramètres d'analyse

Les fonctions internes PHP utilisent zend_parse_parameters lors de l'analyse des paramètres. Il peut grandement simplifier le travail de réception et de traitement des paramètres, même s'il reste un peu faible lorsqu'il s'agit de paramètres variables.

Il est déclaré comme suit :

ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, 
...)
Le premier paramètre num_args indique le nombre de paramètres que vous souhaitez recevoir. Nous utilisons souvent ZEND_NUM_ARGS() pour indiquer "combien de paramètres sont passés. "Combien ?"

Le deuxième paramètre doit être la macro TSRMLS_CC.

Le troisième paramètre type_spec est une chaîne utilisée pour spécifier le type de chaque paramètre que nous espérons recevoir, un peu similaire à la

chaîne formatée qui spécifie le format de sortie dans printf.

Les paramètres restants sont des pointeurs vers des variables que nous utilisons pour recevoir les valeurs des paramètres PHP.

zend_parse_parameters() convertit le type de paramètre autant que possible lors de l'analyse des paramètres, afin de garantir que nous pouvons toujours obtenir le type de variable attendu

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn