PHP擴充中定義一個類

來源:互聯網
上載者:User

在PHP擴充中定義一個類,是非常容易的,見地址:

https://github.com/walu/phpbook/blob/master/10.1.md

 

類的結構體定義:

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;  /*  普通類,介面,或者抽象類別 */

    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;

}; 

 

定義一個類,關鍵就這麼幾行:

zend_class_entry *myclass_ce;

static zend_function_entry myclass_method[] = {
    { NULL, NULL, NULL }
};

ZEND_MINIT_FUNCTION(sample3)
{
    zend_class_entry ce;

    //"myclass"是這個類的名稱。
    INIT_CLASS_ENTRY(ce, "myclass",myclass_method);
    myclass_ce = zend_register_internal_class(&ce TSRMLS_CC);
    return SUCCESS;

 

層層展開宏INIT_CLASS_ENTRY :

  #define INIT_CLASS_ENTRY(class_container, class_name, functions) \

    INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, NULL, 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 INIT_OVERLOADED_CLASS_ENTRY_EX(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;                            \
    }

 通過展開宏,我發現,在執行完INIT_CLASS_ENTRY後,其實zend_class_entry結構,只初始化了三個成員,name,name_length,builtin_functions 

其中builtin_functions指向自己定義的類的方法數組。

 

註冊類的最後一步:

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); /* 這一步,主要是完成zend_class_entry結構的各種HashTable成員的初始化,如default_properties,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); /* 這一步,完成zend_class_entry結構中各種函數指標的賦值,如果我們在builtin_functions中實現了這個方法的話,比如各種__call,__get,__set以及constructor,destructor方法等。 */
    }

    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); /* 最後,將類添加到runtime 的全域class_table這個HashTable中,這裡將類名轉成lowercase的了,所以類名不區分大小寫 */
    free(lowercase_name);
    return class_entry;

 

到這裡,也就完成類的註冊了...

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.