Heim  >  Artikel  >  Backend-Entwicklung  >  Vertiefte Kenntnisse der Parameterübergabe von benutzerdefinierten PHP-Funktionen

Vertiefte Kenntnisse der Parameterübergabe von benutzerdefinierten PHP-Funktionen

伊谢尔伦
伊谢尔伦Original
2017-06-26 13:29:151532Durchsuche

Funktionsparameter

Die Definition einer Funktion ist lediglich ein Prozess der Registrierung des Funktionsnamens in der Funktionsliste.

1. Parameter der benutzerdefinierten Funktion

Wir wissen, dass die Parameterprüfung der Funktion durch die Funktion zend_do_receive_arg implementiert wird Parameter ist wie folgt:

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;
Die gesamte Parameterübertragung wird durch Zuweisen von Werten zum arg_info-Feld des Zwischencodes abgeschlossen. Der entscheidende Punkt liegt im Feld arg_info. Die Struktur des Felds arg_info ist wie folgt:

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;
Der Unterschied zwischen Parameterwertübergabe und Parameterübergabe wird durch den Parameter pass_by_reference beim Generieren von Zwischencode erreicht.

In Bezug auf die Anzahl der Parameter wird das im Zwischencode enthaltene Feld arg_nums bei jeder Ausführung von **zend_do_receive_argxx um 1 erhöht:

CG(active_op_array)->num_args++;
Und der Index von Der aktuelle Parameter ist CG(active_op_array)->num_args-1 Der folgende Code:

cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
Die obige Analyse gilt für die Parametereinstellungen, wenn die Funktion definiert ist, und diese Parameter sind festgelegt. Wenn wir tatsächlich ein Programm schreiben, können wir

variable Parameter verwenden. Zu diesem Zeitpunkt werden wir die Funktionen func_num_args und func_get_args verwenden. Sie existieren als interne Funktionen. Suchen Sie also die Implementierung dieser beiden Funktionen in der Datei Zendzend_builtin_functions.c. Schauen wir uns zunächst die Implementierung der Funktion func_num_args an. Der Code lautet wie folgt:

/* {{{ 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);
    }
}
/* }}} */
Wenn ex->function_state.arguments vorhanden ist und wenn die Funktion aufgerufen wird, ist ex->function_state.arguments vorhanden wird nach dem Konvertierungswert zurückgegeben, andernfalls wird ein Fehler angezeigt und -1 zurückgegeben. Der kritischste Punkt hier ist EG (current_execute_data). Diese Variable speichert die Daten des aktuell ausgeführten Programms oder der Funktion. Zu diesem Zeitpunkt müssen wir die Daten des zuvor ausgeführten Programms abrufen. Warum wird der Aufruf dieser Funktion ausgeführt? Die relevanten Daten der Funktion befinden sich alle im vorherigen Ausführungsprozess, daher lautet der Aufruf:

zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
2. Parameter der internen Funktion

Am Beispiel der gemeinsamen Zählfunktion: Sein Parameterverarbeitungsteil Der Code lautet wie folgt:

/* {{{ 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;
    }
    ... //省略
}
Dies umfasst zwei Vorgänge: Der eine besteht darin, die Anzahl der Parameter abzurufen, und der andere darin, die Parameterliste zu analysieren.

(1) Abrufen der Anzahl der Parameter

Das Abrufen der Anzahl der Parameter wird durch das Makro ZEND_NUM_ARGS() erreicht, das wie folgt definiert ist:

#define ZEND_NUM_ARGS()     (ht)
ht ist ht im Makro INTERNAL_FUNCTION_PARAMETERS, das in der Zend/zend.h-Datei wie folgt definiert ist

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value,
zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
(2) Parameterliste analysieren

PHP-interne Funktionen verwenden zend_parse_parameters beim Parsen von Parametern. Es kann die Arbeit beim Empfangen und Verarbeiten von Parametern erheblich vereinfachen, ist jedoch beim Umgang mit variablen Parametern immer noch etwas schwach.

Es wird wie folgt deklariert:

ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, 
...)
Der erste Parameter num_args gibt die Anzahl der Parameter an, die Sie empfangen möchten. Wir verwenden häufig ZEND_NUM_ARGS(), um anzugeben, „wie viele Parameter übergeben werden“. „Wie viel?“

Der zweite Parameter sollte das Makro TSRMLS_CC sein.

Der dritte Parameter type_spec ist eine Zeichenfolge, die verwendet wird, um den Typ jedes Parameters anzugeben, den wir erwarten, ähnlich der

formatierten Zeichenfolge , die das Ausgabeformat in printf angibt.

Die übrigen Parameter sind Zeiger auf Variablen, die wir zum Empfangen von PHP-Parameterwerten verwenden.

zend_parse_parameters() konvertiert den Parametertyp beim Parsen der Parameter so weit wie möglich, um sicherzustellen, dass wir immer den erwarteten Variablentyp erhalten können

Das obige ist der detaillierte Inhalt vonVertiefte Kenntnisse der Parameterübergabe von benutzerdefinierten PHP-Funktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn