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));
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 # という静的変数があります。 ##, その関数は次のとおりです
zend_rsrc_list_dtors_entry#つまり、リソース タイプ R1 が作成されると、リソース タイプ R1 は # に格納されます。 ##list_destructors
パーツ
には、リソース R1 に関する情報が含まれています zend_hash_index_find_ptr
は、以下に対応する
を検索します。リソースを取得し、 lde->type_name
type メンバーが存在する場合、それがリソース タイプであることを意味します。
is_* PHP で型を決定するために使用される一連の関数。そのほとんどは、基になる zval で
u1 を使用します。変数 .v.type のtype 値を決定するには、それがリソース タイプの場合、対応するリソース タイプが list_destructors を通じて存在するかどうかをクエリする必要があります。存在する場合、リソース ハンドルが正常に使用できることを意味します。 PHP 関連の技術記事の詳細については、
PHP チュートリアル
列にアクセスして学習してください。
以上がPHP ソース コード — is_array 関数のソース コード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。