Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Quellcode – Analyse des Quellcodes der Funktion is_array

PHP-Quellcode – Analyse des Quellcodes der Funktion is_array

步履不停
步履不停Original
2019-06-25 15:34:562626Durchsuche

PHP-Quellcode – Analyse des Quellcodes der Funktion is_array

is_array in PHP

is_array in PHP, seine Signatur ist is_array ( mixed $var ) : bool

Implementierung Der Quellcode von

finden Sie in extstandardtype.c , wo sich PHP_FUNCTION(is_array) befindet, ungefähr in Zeile 273.

In PHP besteht diese Funktionsreihe aus vielen Funktionen. Zusätzlich zu sich selbst gibt es auch is_bool, is_countable, is_callback, is_int, is_object, is_string usw.

Dazwischen die meisten Der Quellcode ähnelt is_array:

PHP_FUNCTION(is_array)
{
php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
}

Seine Definition ist sehr prägnant, er ruft php_is_type direkt auf. Die Funktion des Makros INTERNAL_FUNCTION_PARAM_PASSTHRU besteht darin, die Parameter beim Aufruf von is_array zu übergeben. Wird unverändert an php_is_type übergeben . Sie ist wie folgt definiert:

#define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value

Die Funktion php_is_type ist wie folgt definiert:

static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
{
zval *arg;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(arg)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
if (Z_TYPE_P(arg) == type) {
if (type == IS_RESOURCE) {
const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
if (!type_name) {
RETURN_FALSE;
}
}
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}

Die ersten paar Zeilen sind der Parameter-Parsing-Teil

ZEND_PARSE_PARAMETERS_START(1, 1)
    Z_PARAM_ZVAL(arg)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

und dann der Typ des Die Variable wird durch Z_TYPE_P(arg) erhalten und das Ergebnis soll dann gleich IS_ARRAY sein. Wenn „true“, bedeutet dies, dass die Variable ein Array ist, andernfalls ist sie es nicht. Die Rolle von Z_TYPE_P ist offensichtlich, sie besteht darin, den Typ der Variablen zu ermitteln. Dieses Makro wird wie folgt erweitert:

static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
return pz->u1.v.type;
}

wobei pz der zval-Zeiger ist und zval das oft erwähnte _zval_struct:

struct _zval_struct {
zend_value        value;/* 值 */
union {
struct {
ZEND_ENDIAN_LOHI_3(
zend_uchar    type,/* 类型 */
zend_uchar    type_flags,
union {
uint16_t  call_info;    /* call info for EX(This) */
uint16_t  extra;        /* not further specified */
} u)
} v;
uint32_t type_info;
} u1;
union {
uint32_t     next;                 /* hash 碰撞时用到的链表 */
uint32_t     cache_slot;           /* cache slot (for RECV_INIT) */
uint32_t     opline_num;           /* opline number (for FAST_CALL) */
uint32_t     lineno;               /* 行号 (ast 节点中) */
uint32_t     num_args;             /* 参数数量 for EX(This) */
uint32_t     fe_pos;               /* foreach 时的所在位置 */
uint32_t     fe_iter_idx;          /* foreach iterator index */
uint32_t     access_flags;         /* 类时的访问权限标志位 */
uint32_t     property_guard;       /* single property guard */
uint32_t     constant_flags;       /* constant flags */
uint32_t     extra;                /* 保留字段 */
} u2;
};

Es wird keine ausführliche Einführung gegeben.

Weiterlesen

Bei der Beurteilung des Typs php_is_type

Es gibt einen seltsamen Ort:

if (type == IS_RESOURCE) {

Warum muss beurteilt werden, ob es sich um einen Ressourcentyp handelt? ?

Erweiterter Ressourcentyp

Hier erweitern, wenn Sie php_is_type verwenden, um den Ressourcentyp zu bestimmen

Dadurch wird

const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));Es gibt einen Aufruf von zend_rsrc_list_get_rsrc_type, seine Implementierung ist wie folgt:

const char *zend_rsrc_list_get_rsrc_type(zend_resource *res)
{
zend_rsrc_list_dtors_entry *lde;
lde = zend_hash_index_find_ptr(&list_destructors, res->type);
if (lde) {
return lde->type_name;
} else {
return NULL;
}
}

hat eine statische Variable namens

, ihre Funktion ist wie folgt

list_destructors

list_destructors ist eine globale statische HashTable , Ressourcentyp Bei der Registrierung wird eine zval-Strukturvariable zv in den arData von list_destructors gespeichert, und der value.ptr von zv zeigt auf zend_rsrc_list_dtors_entry *lde Der Ressourcenfreigabefunktionszeiger, der persistente Ressourcenfreigabefunktionszeiger und der in lde enthaltene Ressourcentyp Name, Indexbasis der Ressource in der Hashtabelle (resource_id) usw. --Aus „Analyse des Drittanbieter-Erweiterungsprinzips der Verwendung von Resource Wrapping in PHP7“

Mit anderen Worten: Wenn ein Ressourcentyp R1 erstellt wird, wird eine Kopie in
, das einige Informationen über die Ressource R1 enthält

list_destructorsDas zend_rsrc_list_dtors_entry hier dient dazu, das

zu finden, das der Ressource entspricht, und dann das

zend_hash_index_find_ptr zend_rsrc_list_dtors_entry zu verwenden, wenn der Typ vorliegt Wenn ein Mitglied vorhanden ist, bedeutet dies, dass es sich um einen Ressourcentyp handelt. lde->type_name

Zusammenfassung

PHP verwendet die -Reihe von Funktionen, um den Typ zu bestimmen. Die meisten von ihnen verwenden zur Bestimmung den

im zugrunde liegenden zval der Variablen Wenn dies der Fall ist, müssen Sie über list_destructors abfragen, ob der entsprechende Ressourcentyp vorhanden ist. Dies bedeutet, dass das Ressourcenhandle normal verwendet werden kann.

is_* Weitere technische Artikel zum Thema PHP finden Sie in der Spalte u1.v.type PHP-Tutorial

, um mehr darüber zu erfahren!

Das obige ist der detaillierte Inhalt vonPHP-Quellcode – Analyse des Quellcodes der Funktion is_array. 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