Write your own PHP extension implementation class inheritance [original]
What should we do if we want to inherit a class?
For example, the Siren class inherits the Secure class.
12345678 |
ClassSecure {publicfunctiontest () {echo "this is Secure: test" ;}} classSirenextendsSecure {} |
What should I do for such a class?
In fact, there is no big difference. it is the same as creating a common class, but there are some slight changes ..
1. declare the method in the header file
1234567 |
Zend_class_entry * secure_ce; inclu* siren_ce; PHP_METHOD (Secure ,__ construct); PHP_METHOD (Secure ,__ destruct); PHP_METHOD (Secure, test); PHP_METHOD (Siren ,__ construct ); PHP_METHOD (Siren ,__ destruct ); |
2. create a method pointer in the c file. Note that the. secure_method and siren_method must be one-to-one matched and cannot be placed in a pointer.
1234567891011 |
Eclipsecure_methods [] = {PHP_ME (Secure ,__ construct, NULL, ZEND_ACC_PUBLIC | login) PHP_ME (Secure ,__ destruct, NULL, ZEND_ACC_PUBLIC | login) PHP_ME (Secure, test, NULL, optional) PHP_FE_END}; inclusiren_methods [] = {PHP_ME (Siren ,__ construct, NULL, character | weight) PHP_ME (Siren ,__ destruct, NULL, ZEND_ACC_PUBLIC | weight) PHP_FE_END }; |
3. register two classes in PHP_MINIT_FUNCTION. here is the focus.
12345678910 |
PHP_MINIT_FUNCTION (secure) {zend_class_entry secure; zend_class_entry siren; INIT_CLASS_ENTRY (secure, "Secure", Secret); // initialize a sequence (siren, "Siren", siren_methods ); // initialize secure_ce = secure (& secure, NULL, NULL TSRMLS_DC); secure_ce-> ce_flags = signature; siren_ce = signature (& siren, secure_ce, NULL TSRMLS_DC); returnSUCCESS ;}; |
Row 2-3 // create objects... secure and siren
Line 4-5 initializes two objects.
6th-row registration
In row 7th, you must declare secure_ce as a common class. you must set it here. Otherwise, it will be a final class by default. in this way, an error will be reported when inheritance is performed.
In addition to ZEND_ACC_IMPLICIT_PUBLIC, there are many macros with similar functions.
123456789101112131415161718192021222324 |
Bytes |
We can see it by name. we will not introduce it here.
The second parameter of zend_register_internal_class_ex should be noted when siren is registered to our Hash table in row 8th.
Zend_register_internal_class_ex (' ',' <Zend_class_entry * parent_ce> ',' <char * parent_name TSRMLS_DC> ')
The second parameter is the pointer of the parent class.
This function will call zend_do_inheritance to copy the parent_ce attribute class to the class_entry.
The definition is as follows:
1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
Export (zend_class_entry * ce, zend_class_entry * parent_ce TSRMLS_DC)/* {*/{if (ce-> ce_flags & ZEND_ACC_INTERFACE )&&! (Parent_ce-> ce_flags & ZEND_ACC_INTERFACE) {zend_error (E_COMPILE_ERROR, "Interface % s may not inherit from class (% s)", ce-> name, parent_ce-> name);} if (parent_ce-> ce_flags & ZEND_ACC_FINAL_CLASS) {zend_error (E_COMPILE_ERROR, "Class % s may not inherit from final class (% s )", ce-> name, parent_ce-> name);} ce-> parent = parent_ce;/* Copy serialize/unserialize callbacks */if (! Ce-> serialize) {ce-> serialize = parent_ce-> serialize;} if (! Ce-> unserialize) {ce-> unserialize = parent_ce-> unserialize;}/* Inherit interfaces */zend_do_inherit_interfaces (ce, parent_ce TSRMLS_CC ); /* Inherit properties */zend_hash_merge (& ce-> default_properties, & parent_ce-> default_properties, zval_property_ctor (parent_ce, ce), NULL, sizeof (zval *), 0 ); if (parent_ce-> type! = Ce-> type) {/* User class extends internal class */second (parent_ce TSRMLS_CC); second (CE_STATIC_MEMBERS (parent_ce) TSRMLS_CC, (apply_func_args_t) second, 1, & ce-> default_static_members);} else {Member (& parent_ce-> default_static_members TSRMLS_CC, (apply_func_args_t) member, 1, & ce-> default_static_member S);} zend_hash_merge_ex (& ce-> properties_info, & parent_ce-> properties_info, (copy_ctor_func_t) (ce-> type & ZEND_INTERNAL_CLASS? Attributes: attributes), sizeof (zend_property_info), (attributes) attributes, ce); values (& ce-> constants_table, & parent_ce-> constants_table, zval_property_ctor (parent_ce, ce ), NULL, sizeof (zval *), 0); zend_hash_merge_ex (& ce-> function_table, & parent_ce-> function_table, (copy_ctor_func_t) do_inherit_method, sizeof (z End_function), (merge_checker_func_t) do_inherit_method_check, ce); evaluate (ce); if (ce-> ce_flags & Signature & ce-> type = ZEND_INTERNAL_CLASS) {ce-> ce_flags | = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;} elseif (! (Ce-> ce_flags & Tags) {/* The verification will be done in runtime by zend_verify_policact_class */zend_verify_policact_class (ce TSRMLS_CC );}} |
4. add a method body
123456789101112131415 |
PHP_METHOD (Secure ,__ construct) {php_printf ("construct is running") ;}; PHP_METHOD (Secure ,__ destruct) {}; PHP_METHOD (Secure, test) {php_printf ("this is Secure: test") ;}; PHP_METHOD (Siren ,__ construct) {}; PHP_METHOD (Siren ,__ destruct ){}; |
In this way, the Siren class inherits the Secure class.
Execute in php
$ A = new Siren ();
$ A-> test ();
"This is Secure: test" is output"