Define a class in PHP Extension

Source: Internet
Author: User

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...

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.