Defining a class in PHP extensions is very easy. See the address:
Https://github.com/walu/phpbook/blob/master/10.1.md
Struct definition of the class:
Struct _ zend_class_entry {
Char type;
Char * name;
Zend_uint name_length;
Struct _ zend_class_entry * parent;
Int refcount;
Zend_bool constants_updated;
Zend_uint ce_flags;/* Common class, interface, or abstract class */
HashTable function_table;
HashTable default_properties;
HashTable properties_info;
HashTable default_static_members;
HashTable * static_members;
HashTable constants_table;
Const struct _ zend_function_entry * builtin_functions;
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 * _ callstatic;
Union _ zend_function * _ tostring;
Union _ zend_function * serialize_func;
Union _ zend_function * unserialize_func;
Zend_class_iterator_funcs iterator_funcs;
/* Handlers */
Zend_object_value (* create_object) (zend_class_entry * class_type TSRMLS_DC );
Zend_object_iterator * (* get_iterator) (zend_class_entry * ce, zval * object, int by_ref TSRMLS_DC );
Int (* interface_gets_implemented) (zend_class_entry * iface, zend_class_entry * class_type TSRMLS_DC);/* a class implements this interface */
Union _ zend_function * (* get_static_method) (zend_class_entry * ce, char * method, int method_len TSRMLS_DC );
/* Serializer callbacks */
Int (* serialize) (zval * object, unsigned char ** buffer, zend_uint * buf_len, zend_serialize_data * data TSRMLS_DC );
Int (* unserialize) (zval ** object, zend_class_entry * ce, const unsigned char * 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;
};
The key to defining a class is as follows:
Zend_class_entry * myclass_ce;
Static zend_function_entry myclass_method [] = {
{NULL, NULL, NULL}
};
ZEND_MINIT_FUNCTION (sample3)
{
Zend_class_entry ce;
// "Myclass" is the name of this class.
INIT_CLASS_ENTRY (ce, "myclass", myclass_method );
Myclass_ce = zend_register_internal_class (& ce TSRMLS_CC );
Return SUCCESS;
}
Expand the macro INIT_CLASS_ENTRY layer by layer:
# Define INIT_CLASS_ENTRY (class_container, class_name, functions )\
INIT_OVERLOADED_CLASS_ENTRY (class_container, class_name, functions, NULL, NULL)
# Define INIT_OVERLOADED_CLASS_ENTRY (class_container, class_name, functions, handle_fcall, handle_propget, handle_propset )\
INIT_OVERLOADED_CLASS_ENTRY_EX (class_container, class_name, sizeof (class_name)-1, functions, handle_fcall, handle_propget, handle_propset, NULL, NULL)
# Define compile (class_container, class_name, class_name_len, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset )\
{\
Int _ len = class_name_len ;\
Class_container.name = zend_strndup (class_name, _ len );\
Class_container.name_length = _ len ;\
Class_container.builtin_functions = functions ;\
Class_container.constructor = NULL ;\
Class_container.destructor = NULL ;\
Class_container.clone = NULL ;\
Class_container.serialize = NULL ;\
Class_container.unserialize = NULL ;\
Class_container.create_object = NULL ;\
Class_container.interface_gets_implemented = NULL ;\
Class_container.get_static_method = NULL ;\
Class_container. _ call = handle_fcall ;\
Class_container. _ callstatic = NULL ;\
Class_container. _ tostring = NULL ;\
Class_container. _ get = handle_propget ;\
Class_container. _ set = handle_propset ;\
Class_container. _ unset = handle_propunset ;\
Class_container. _ isset = handle_propisset ;\
Class_container.serialize_func = NULL ;\
Class_container.unserialize_func = NULL ;\
Class_container.serialize = NULL ;\
Class_container.unserialize = NULL ;\
Class_container.parent = NULL ;\
Class_container.num_interfaces = 0 ;\
Class_container.interfaces = NULL ;\
Class_container.get_iterator = NULL ;\
Class_container.iterator_funcs.funcs = NULL ;\
Class_container.module = NULL ;\
}
By expanding the macro, I found that after INIT_CLASS_ENTRY is executed, the zend_class_entry structure only initializes three members: name, name_length, builtin_functions
Builtin_functions points to the method array of the defined class.
The last step of the registration class:
ZEND_API zend_class_entry * zend_register_internal_class (zend_class_entry * orig_class_entry TSRMLS_DC )/*{{{*/
{
Return do_register_internal_class (orig_class_entry, 0 TSRMLS_CC );
}
Static zend_class_entry * do_register_internal_class (zend_class_entry * orig_class_entry, zend_uint ce_flags TSRMLS_DC )/*{{{*/
{
Zend_class_entry * class_entry = malloc (sizeof (zend_class_entry ));
Char * lowercase_name = malloc (orig_class_entry-> name_length + 1 );
* Class_entry = * orig_class_entry;
Class_entry-> type = ZEND_INTERNAL_CLASS;
Zend_initialize_class_data (class_entry, 0 TSRMLS_CC);/* this step completes initialization of various HashTable members in the zend_class_entry structure, such as default_properties and properties_info */
Class_entry-> ce_flags = ce_flags;
Class_entry-> module = EG (current_module );
If (class_entry-> builtin_functions ){
Zend_register_functions (class_entry, class_entry-> builtin_functions, & class_entry-> function_table, MODULE_PERSISTENT TSRMLS_CC);/* assign values to function pointers in the zend_class_entry structure, if we implement this method in builtin_functions, for example, various _ call ,__ get ,__ set and constructor and destructor methods. */
}
Zend_str_tolower_copy (lowercase_name, orig_class_entry-> name, class_entry-> name_length );
Zend_hash_update (CG (class_table), lowercase_name, class_entry-> name_length + 1, & class_entry, sizeof (zend_class_entry *), NULL);/* Finally, add the class to the HashTable in the global class_table of runtime. Here, the class name is converted to lowercase, so the class name is case insensitive */
Free (lowercase_name );
Return class_entry;
}
At this point, the class registration is completed...