>  기사  >  백엔드 개발  >  이 기사에서는 php7의 zval을 분석하는 방법을 안내합니다.

이 기사에서는 php7의 zval을 분석하는 방법을 안내합니다.

藏色散人
藏色散人앞으로
2021-09-15 17:15:102996검색

Zval은 PHP에서 가장 중요한 데이터 구조 중 하나입니다. 여기에는 PHP의 변수 값과 유형에 대한 정보가 포함되어 있습니다.

1. zval

1.1 zval의 구조(zend_types.h)

typedef struct _zval_struct     zval;struct _zval_struct {
    zend_value        value;            /* value */
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                zend_uchar    type,         /* active type */
                zend_uchar    type_flags,
                zend_uchar    const_flags,
                zend_uchar    reserved)     /* call info for EX(This) */
        } v;
        uint32_t type_info;
    } u1;
    union {
        uint32_t     var_flags;
        uint32_t     next;                 /* hash collision chain */
        uint32_t     cache_slot;           /* literal cache slot */
        uint32_t     lineno;               /* line number (for ast nodes) */
        uint32_t     num_args;             /* arguments number for EX(This) */
        uint32_t     fe_pos;               /* foreach position */
        uint32_t     fe_iter_idx;          /* foreach iterator index */
    } u2;};

zval 구조는 비교적 간단하며 세 부분으로 구성됩니다.

  • zend_value: 특정 변수 유형의 값 또는 포인터를 저장합니다.
  • 핵심 u1의 함수는
  • u2타입을 보조값

으로 구별합니다. zval의 구조와 핵심필드의 값을 좀 더 직관적으로 보기 위해 위의 사진을 찍어보겠습니다.
이 기사에서는 php7의 zval을 분석하는 방법을 안내합니다.

u1.v.type에 대한 설명:

  1. IS_UNDEF: 표시가 정의되지 않아 데이터를 덮어쓰거나 삭제할 수 있음을 나타냅니다. 예를 들어, 배열 요소에 대해 설정 해제 작업을 수행할 때 PHP 7은 HashTable에 할당된 메모리에서 데이터를 직접 삭제하지 않고 먼저 요소가 있는 버킷의 위치를 ​​IS_UNDEF로 표시합니다. HashTable의 IS_UNDEF 요소 수는 특정 임계값에 도달하면 재해시 작업 중에 IS_UNDEF로 표시된 요소를 덮어쓰거나 삭제합니다.
  2. IS_TRUE 및 IS_FALSE: 여기서 IS_BOOL은 두 가지로 최적화되어 있으며, Boolean 유형 태그는 유형에 직접 기록됩니다.
  3. IS_REFERENCE: PHP7은 "&"를 처리하기 위해 다른 처리 방법을 사용합니다.
  4. IS_INDIRECT: PHP 7의 HashTable 디자인이 PHP5와 매우 다르기 때문에 새로운 유형입니다. CV 변수 테이블에 대한 전역 기호 테이블 액세스 문제를 해결하기 위해 IS_INDRECT 유형이 도입되었습니다.
  5. IS_PTR: 이 유형은 일반적으로 함수 유형에 사용되는 value.ptr을 구문 분석하는 데 사용되는 포인터 유형으로 정의됩니다. 예를 들어 함수나 메서드를 선언합니다.

1.2 zend_value

zval에서 zend_value의 정의는 다음과 같습니다.

typedef union _zend_value {
    zend_long         lval;             /* long value */
    double            dval;             /* double value */
    zend_refcounted  *counted;
    zend_string      *str;
    zend_array       *arr;
    zend_object      *obj;
    zend_resource    *res;
    zend_reference   *ref;
    zend_ast_ref     *ast;
    zval             *zv;
    void             *ptr;
    zend_class_entry *ce;
    zend_function    *func;
    struct {
        uint32_t w1;
        uint32_t w2;
    } ww;
} zend_value;

1.3 zval 메모리 사용량

zval에서:

  • zend_value는 합집합이며 8바이트만 차지합니다. zend_long, double 또는 포인터를 저장하기에 충분합니다.
  • u1은 4바이트이고 v 또는 type_info를 저장합니다.
  • u2는 4바이트이므로

이 기사에서는 php7의 zval을 분석하는 방법을 안내합니다.

zval은 16바이트를 차지합니다. 이에 따라 php5에서는 zval의 크기가 48바이트로, 이는 실제로 엄청난 개선입니다.

2. 변수 저장

2.1 true, false, null

은 zend_value의 참여 없이 zval.u1.v.type에 따라 직접 구별 가능

2.2 long, double

은 lval 또는 zend_value의 dval.

2.3 기타 유형(문자열, 배열, 개체, 리소스 등)

zend_value에 해당하는 포인터를 사용하여 특정 구조를 가리킵니다.

예를 들어 문자열 유형의 구조는

struct _zend_string {
    zend_refcounted_h gc;
    zend_ulong        h;                /* hash value */
    size_t            len;
    char              val[1];
};

문자열 변수의 메모리 구성은 아래 그림과 같으며, zval.value.str은 zend_string 구조를 가리킵니다.
이 기사에서는 php7의 zval을 분석하는 방법을 안내합니다.

Zval은 PHP에서 가장 중요한 데이터 구조 중 하나입니다. 여기에는 PHP의 변수 값과 유형에 대한 정보가 포함되어 있습니다.

추천 학습: "PHP7 튜토리얼"

위 내용은 이 기사에서는 php7의 zval을 분석하는 방법을 안내합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제