ホームページ  >  記事  >  バックエンド開発  >  PHP ソース コード — is_array 関数のソース コード分析

PHP ソース コード — is_array 関数のソース コード分析

步履不停
步履不停オリジナル
2019-06-25 15:34:562622ブラウズ

PHP ソース コード — is_array 関数のソース コード分析

php の is_array

php の is_array、その署名は is_array (mixed $var): bool

実装のソース コード

は、 \ext\standard\type.c PHP_FUNCTION(is_array) にあります。場所は273号線あたりです。

PHP では、この一連の関数は多くの関数で構成されており、それ自体の他に、is_bool、is_countable、is_callback、is_int、is_object、is_string などもあります。

これらの間のほとんどの関数は、ソース コードのソース コードは is_array に似ています:

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

その定義は非常に簡潔で、 php_is_type を直接呼び出し、マクロの関数 INTERNAL_FUNCTION_PARAM_PASSTHRU は、次の場合にパラメータを渡します。 is_array をそのまま php_is_type に呼び出します。次のように定義されます:

#define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value

関数 php_is_type は次のように定義されます:

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

最初の数行はパラメータ解析部分です

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

その後、渡されます Z_TYPE_P(arg) 変数の型を取得し、結果を IS_ARRAY と等しくします。 true の場合は変数が配列であることを意味し、それ以外の場合は配列ではありません。 Z_TYPE_P の役割は明らかで、変数の型を取得することです。このマクロを展開すると、次のようになります:

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

ここで、pz は zval ポインター、zval はよく言及される ## です# _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;
};

詳しい紹介はしません。

続きを見る

php_is_type型を判断する際、

変なところがあります:

if (type == IS_RESOURCE) {

リソース タイプであるかどうかを判断する必要があるのはなぜですか?

拡張リソース タイプ

ここで拡張します。php_is_type を使用してリソース タイプを決定する場合は、

ここで呼び出されます

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

zend_rsrc_list_get_rsrc_type への呼び出しがあり、次のように実装されます:

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

list_destructors # という静的変数があります。 ##, その関数は次のとおりです

list_destructors はグローバルな静的 HashTable であり、リソースタイプを登録すると list_destructors の arData に zval 構造体変数 zv が格納されますが、value.ptr はof zv は zend_rsrc_list_dtors_entry *lde を指し、lde に含まれるリソース解放関数ポインタ、永続リソースの解放関数ポインタ、リソースタイプ名、ハッシュテーブル内のリソースのインデックスベース (resource_id) などです。 --「PHP7 におけるリソース ラッピングを使用したサードパーティ拡張原則の分析」より

#つまり、リソース タイプ R1 が作成されると、リソース タイプ R1 は # に格納されます。 ##list_destructors

パーツ
zend_rsrc_list_dtors_entry

には、リソース R1 に関する情報が含まれています zend_hash_index_find_ptr は、以下に対応する

zend_rsrc_list_dtors_entry

を検索します。リソースを取得し、 lde->type_nametype メンバーが存在する場合、それがリソース タイプであることを意味します。

概要

is_* PHP で型を決定するために使用される一連の関数。そのほとんどは、基になる zval で

u1 を使用します。変数 .v.type の

type 値を決定するには、それがリソース タイプの場合、対応するリソース タイプが list_destructors を通じて存在するかどうかをクエリする必要があります。存在する場合、リソース ハンドルが正常に使用できることを意味します。 PHP 関連の技術記事の詳細については、PHP チュートリアル 列にアクセスして学習してください。

以上がPHP ソース コード — is_array 関数のソース コード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。