PHPer에게 OOP는 필수적인 개발 사고방식인데, PHP 클래스와 객체의 기본 구현에 대해 얼마나 알고 계시나요? 무슨 일이 일어나고 있는지, 왜 그런지 안다는 생각을 바탕으로 함께 답을 찾아보자~
클래스의 기본 구현은 우리가 이야기한 변수, 함수 등에 대한 지식의 집합이라고 볼 수 있다 약 전에. 따라서 더 깊이 이해하고 싶은 학생들은 변수 및 함수 소개에 대한 이전 기사를 확인해야 합니다
일반 클래스든 추상 클래스든 인터페이스든 모두 통일된 구조로 저장됩니다. 중간 코드를 사용하면 이 클래스가 전역 클래스 목록에 추가됩니다. 물론 이때 클래스가 이미 존재하는지 여부는 클래스 이름으로 판단됩니다. 존재한다면 추가는 실패합니다
struct _zend_class_entry { char type; // 和函数一样,类被拆分为两种类型:ZEND_INTERNAL_CLASS 内部类型和ZEND_USER_CLASS 用户自定义类型 char *name;// 类名称 zend_uint name_length; // 即sizeof(name) - 1 struct _zend_class_entry *parent; // 继承的父类 int refcount; // 引用数 zend_bool constants_updated; zend_uint ce_flags; //类的类型,在编译阶段被区分是普通类,接口,抽象类 HashTable function_table; // 静态类方法和普通类方法存放集合 HashTable default_properties; // 默认属性存放集合 HashTable properties_info; // 属性信息存放集合 HashTable default_static_members;// 类本身所具有的静态变量存放集合 HashTable *static_members; // type == ZEND_USER_CLASS时,取&default_static_members; // type == ZEND_INTERAL_CLASS时,设为NULL HashTable constants_table; // 常量存放集合 struct _zend_function_entry *builtin_functions;// 方法定义入口 /* 魔术方法 */ //所有魔术方法单独存放,初始化时被设置为null union _zend_function *constructor; union _zend_function *destructor; union _zend_function *clone; union _zend_function *__get; union _zend_function *__set; union _zend_function *__unset; union _zend_function *__isset; union _zend_function *__call; union _zend_function *__tostring; union _zend_function *serialize_func; union _zend_function *unserialize_func; zend_class_iterator_funcs iterator_funcs;// 迭代 /* 类句柄 */ zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC); zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, intby_ref TSRMLS_DC); /* 类声明的接口 */ int(*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* 序列化回调函数指针 */ int(*serialize)(zval *object, unsignedchar**buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC); int(*unserialize)(zval **object, zend_class_entry *ce, constunsignedchar*buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC); zend_class_entry **interfaces; // 类实现的接口 zend_uint num_interfaces; // 类实现的接口数 char *filename; // 类的存放文件地址 绝对地址 zend_uint line_start; // 类定义的开始行 zend_uint line_end; // 类定义的结束行 char *doc_comment; zend_uint doc_comment_len; struct _zend_module_entry *module; // 类所在的模块入口:EG(current_module) };
위 코드에서 알 수 있듯이 클래스의 멤버 변수와 멤버 메소드는 다음과 같습니다. , 구조체의 데이터 구조는 컴파일된 멤버 변수와 멤버 메서드가 클래스 구조에 저장된다는 점을 제외하면 앞서 설명한 변수 및 함수의 데이터 구조와 완전히 동일합니다.
우리 모두는 객체가 새로운 것이라는 것을 알고 있지만 낮은 수준의 관점에서 객체 생성은 세 단계로 나누어집니다.
첫 번째 단계: 클래스 이름에 따라 해당 클래스가 전역 클래스 목록에 존재하는지, 존재하는지 확인합니다. , 저장소 클래스의 변수를 가져옵니다
두 번째 단계: 클래스가 일반 클래스(비추상 클래스 또는 인터페이스)인지 확인합니다. 일반 클래스인 경우 생성할 객체가 있는 zval 컨테이너에 메모리를 할당합니다. 저장하고 컨테이너 유형을 IS_OBJECT
로 설정합니다. 3단계: 개체 초기화를 수행하고 개체를
에 추가합니다. 전역 개체 목록(개체 풀)에 개체의 데이터 구조를 첨부합니다.
typedef struct _zend_object { zend_class_entry *ce; //对象的类结构 HashTable *properties; //对象属性 HashTable *guards; /* protects from __get/__set ... recursion */ } zend_object;
멤버 변수 가져오기:
첫 번째 단계는 개체의 속성을 가져오고 개체의 속성에서 이름이 있는지 확인하는 것입니다. 해당 속성이 있으면 결과를 반환하고, 존재하지 않으면 다음으로 이동합니다. 두 번째 단계에서 get 매직 메서드가 있는 경우 이 메서드를 호출하여 변수를 가져옵니다. 해당 메서드가 없으면 오류가 보고됩니다. 멤버 변수 설정:
첫 번째 단계, 개체의 속성을 가져옵니다. , 객체의 속성에서 이름에 해당하는 속성이 있는지 확인하고, 기존 값이 설정하려는 값과 동일하면 아무런 작업도 수행하지 않습니다. 존재하지 않으면 두 번째 단계로 이동
세 번째 단계에서는 멤버 변수가 설정되지 않은 경우 변수를 직접 설정하고 해당 객체의 속성 필드가 있는 HashTable에 추가합니다.
요약
더 많은 PHP 관련 기술 기사를 보려면 PHP Tutorial 칼럼을 방문하세요. 배우다!
위 내용은 PHP 기본 원칙, 클래스 및 객체의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!