Classes and Objects of php Bottom Principles

Keywords: PHP Attribute

OOP is an indispensable development thought for PHPer, but how much do you know about the underlying implementation of php classes and objects?In the spirit of knowing what it is and knowing what it is, let's find the answer together. ~

The underlying implementation of a class can be considered as a set of knowledge about variables, functions, etc. as we mentioned earlier. So if you want to understand more deeply, you'd better check out my previous articles on introducing variables and functions.

Data structure of class

Both ordinary and abstract classes and interfaces are stored in a unified structure, and when intermediate code is generated, such classes are added to the global class list. Of course, at this point, the class name is used to determine whether the class already exists, and if it exists, the addition fails.

struct _zend_class_entry {
    char type;     // Like functions, classes are split into two types: ZEND_INTERNAL_CLASS internal type and ZEND_USER_CLASS user-defined type.
    char *name;// Class name
    zend_uint name_length;                  // That is sizeof(name) - 1
    struct _zend_class_entry *parent; // Inherited parent class
    int refcount;  // Reference number
    zend_bool constants_updated;
 
    zend_uint ce_flags;    //Class types, which are distinguished during compilation, are common classes, interfaces, and abstract classes.
    HashTable function_table;      // Static class methods and common class methods store collections
    HashTable default_properties;          // Default properties store collections
    HashTable properties_info;     // Attribute Information Storage Set
    HashTable default_static_members;// Static Variables Storage Collection of Classes
    HashTable *static_members; // When type = ZEND_USER_CLASS, take & default_static_members;
    // When type = ZEND_INTERAL_CLASS, set it to NULL
    HashTable constants_table;     // Constant storage set
    struct _zend_function_entry *builtin_functions;// Method Definition Entry
 
    /* Magic Methods */
    //All magic methods are stored separately and initialized as 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;// iteration
 
    /* Class handle */
    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);
 
    /* Interfaces for class declarations */
    int(*interface_gets_implemented)(zend_class_entry *iface,
            zend_class_entry *class_type TSRMLS_DC);
 
 
    /* Serialized callback function pointer */
    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;  //  Class Implementation Interface
    zend_uint num_interfaces;   //  Number of interfaces implemented by class
 
 
    char *filename; //  Address Absolute Address of Class Storage File
    zend_uint line_start;   //  Starting line of class definition
    zend_uint line_end; //  End line of class definition
    char *doc_comment;
    zend_uint doc_comment_len;
 
 
    struct _zend_module_entry *module; // The module entry where the class is located: EG(current_module)
};

As can be seen from the above code, the member variables and member methods of the class are stored in their respective structures. The data structure of the structure is the same as the data structure of the function explained before, except that the compiled member variables and member methods are stored in the class structure.

Object Generation

As we all know, objects are new, but at the bottom, object generation is divided into three steps
Step 1: Find out if the class exists in the global class list according to the class name, and if it exists, get the variables of the storage class.
Step 2: Determine whether the class is a common class (non-abstract class or interface); if it is a common class, allocate memory to the zval container where the object needs to be created, and set the container type IS_OBJECT?
Step 3: Perform object initialization and add objects to the global object list (object pool)

The data structure of the attached object:

typedef struct _zend_object {
    zend_class_entry *ce; //Class structure of objects
    HashTable *properties; //Object attribute
    HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;

Get and set member variables

Get member variables:
The first step is to get the attributes of the object and find out whether there are attributes corresponding to the name from the properties of the object. If there are returned results, if not, go to the second step.
The second step, if there is a get magic method, calls this method to get the variable, and if there is no, the error is reported.

Set member variables:
The first step is to get the attributes of the object and find out whether there are attributes corresponding to the name from the properties of the object. If there are and the existing values are the same as the values that need to be set, no operation will be performed. Otherwise, variable assignment will be performed. If there are no attributes, go to the second step.
The second step, if there is a _set magic method, calls this method to set variables. If not, go to the third step.
Third, if the member variable has never been set, add it directly to the HashTable where the properties field of the object is located.

summary

So far, we've almost gone through the underlying principles of php. Of course, during this period, many students told me that they have gradually started to use php7. What you are talking about now is still php5. Will it be out of date? In fact, I explained PHP5 to prepare for php7. After all, php7 is an extension of php5. After knowing php5, it will be easier to understand php7. And PHP is gradually improved from the beginning of php5, we need to understand the content of php5. But starting next week, we will start to compare the differences between php7 and PHP5 from the bottom. Please look forward to it.~

Posted by geo115fr on Fri, 17 May 2019 22:11:44 -0700