Write your own PHP extension implementation class inheritance

Source: Internet
Author: User
Statement: This article is an original article by the author, all of which have been analyzed by the author one by one. I hope you can give me some advice if there is something wrong with it.
You are welcome to reprint it. Please indicate the source for reprinting.
Address: http://imsiren.com/archives/593

What should we do if we want to inherit a class?

For example, the siren class inherits the secure class.

class Secure{    public function test(){           echo "this is Secure::test";    }}class Siren extends Secure{ }

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

zend_class_entry *secure_ce;zend_class_entry *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.

const zend_function_entry secure_methods[]={        PHP_ME(Secure,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)        PHP_ME(Secure,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)        PHP_ME(Secure,test,NULL,ZEND_ACC_PUBLIC)        PHP_FE_END};const zend_function_entry siren_methods[]={        PHP_ME(Siren,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)        PHP_ME(Siren,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)        PHP_FE_END};

3. register two classes in php_minit_function. Here is the focus.

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); Return success ;};

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.

ZEND_ACC_ABSTRACTZEND_ACC_ALLOW_STATICZEND_ACC_CALL_VIA_HANDLERZEND_ACC_CHANGEDZEND_ACC_CLONEZEND_ACC_CLOSUREZEND_ACC_CTORZEND_ACC_DEPRECATEDZEND_ACC_DTORZEND_ACC_EXPLICIT_ABSTRACT_CLASSZEND_ACC_FINALZEND_ACC_FINAL_CLASSZEND_ACC_IMPLEMENTED_ABSTRACTZEND_ACC_IMPLEMENT_INTERFACESZEND_ACC_IMPLICIT_ABSTRACT_CLASSZEND_ACC_IMPLICIT_PUBLICZEND_ACC_INTERACTIVEZEND_ACC_INTERFACEZEND_ACC_PPP_MASKZEND_ACC_PRIVATEZEND_ACC_PROTECTEDZEND_ACC_PUBLICZEND_ACC_SHADOWZEND_ACC_STATIC

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:

ZEND_API void zend_do_inheritance(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 */                zend_update_class_constants(parent_ce  TSRMLS_CC);                zend_hash_apply_with_arguments(CE_STATIC_MEMBERS(parent_ce) TSRMLS_CC, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);        } else {                zend_hash_apply_with_arguments(&parent_ce->default_static_members TSRMLS_CC, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);        }        zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (copy_ctor_func_t) (ce->type & ZEND_INTERNAL_CLASS ? zend_duplicate_property_info_internal : zend_duplicate_property_info), sizeof(zend_property_info), (merge_checker_func_t) do_inherit_property_access_check, ce);         zend_hash_merge(&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(zend_function), (merge_checker_func_t) do_inherit_method_check, ce);        do_inherit_parent_constructor(ce);         if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) {                ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;        } else if (!(ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES)) {                /* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */                zend_verify_abstract_class(ce TSRMLS_CC);        }}

4. Add a method body

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"

Source: http://imsiren.com/archives/593

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.