Maison  >  Article  >  développement back-end  >  Code source PHP — Analyse du code source de la fonction is_array

Code source PHP — Analyse du code source de la fonction is_array

步履不停
步履不停original
2019-06-25 15:34:562566parcourir

Code source PHP — Analyse du code source de la fonction is_array

is_array en php

is_array en php, sa signature est is_array ( mixed $var ) : bool

implémentation Le code source de

se trouve à extstandardtype.c où se trouve PHP_FUNCTION(is_array) , approximativement à la ligne 273.

En PHP, cette série de fonctions se compose de nombreuses fonctions. En plus d'elle-même, il existe également is_bool, is_countable, is_callback, is_int, is_object, is_string, etc.

Entre eux, la plupart. du code source est similaire à is_array :

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

Sa définition est très concise, elle appelle directement php_is_type , la fonction de la macro INTERNAL_FUNCTION_PARAM_PASSTHRU est de passer les paramètres lors de l'appel de is_array, Passé inchangé à php_is_type . Il est défini comme suit :

#define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value

La fonction php_is_type est définie comme suit :

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;
}
}

Les premières lignes sont la partie d'analyse des paramètres

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

puis le type du La variable est obtenue via Z_TYPE_P(arg) , puis laissez le résultat être égal à IS_ARRAY . Si c'est vrai, cela signifie que la variable est un tableau, sinon ce n'est pas le cas. Le rôle de Z_TYPE_P est évident, il est d'obtenir le type de la variable. Cette macro est développée comme suit :

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

où pz est le pointeur zval, et zval est le _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;
};

Aucune introduction approfondie ne sera donnée.

Continuer à lire

Lors du jugement du type, php_is_type

Il y a un endroit étrange :

if (type == IS_RESOURCE) {

Pourquoi est-il nécessaire de juger s'il s'agit d'un type de ressource ?

Type de ressource étendu

Étendez ici, si vous utilisez php_is_type pour déterminer le type de ressource

Cela appellera

const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));

Il y a un appel à zend_rsrc_list_get_rsrc_type, son implémentation est la suivante :

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;
}
}

a une variable statique appelée

, sa fonction est la suivante list_destructors

list_destructors est une HashTable statique globale , type de ressource Lors de l'enregistrement, une variable de structure zval zv est stockée dans le arData de list_destructors, et le value.ptr de zv pointe vers zend_rsrc_list_dtors_entry *lde Le pointeur de fonction de libération de ressource, le pointeur de fonction de libération de ressource persistante et le type de ressource contenu dans lde. Nom, base d'index de la ressource dans la table de hachage (resource_id), etc. --Extrait de "Analyse du principe d'extension tierce d'utilisation du packaging de ressources en PHP7"

En d'autres termes, lorsqu'une ressource de type R1 est créée, une copie sera stockée dans

list_destructors , qui contient quelques informations sur la ressource R1 zend_rsrc_list_dtors_entry

Le

ici consiste à trouver le zend_hash_index_find_ptr correspondant à la ressource, puis à prendre le zend_rsrc_list_dtors_entry lde->type_name

si le type le membre existe, cela signifie qu’il s’agit d’un type de ressource.

Résumé

PHP utilise la série de fonctions

pour déterminer le type. La plupart d'entre elles utilisent le is_* dans le zval sous-jacent de la variable pour déterminer. la valeur du type. Si c'est le cas pour les types de ressources, vous devez demander si le type de ressource correspondant existe via list_destructors. S'il existe, cela signifie que le descripteur de ressource peut être utilisé normalement. u1.v.type

Pour plus d'articles techniques liés à PHP, veuillez visiter la colonne

Tutoriel PHP pour apprendre !

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