深入PHP内核之面向对象总结(3)

define INIT_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions) INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, NULL, NULL, NULL, 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) {         

const char *cl_name = class_name;     

int _len = class_name_len;             

class_container.name = zend_new_interned_string(cl_name, _len+1, 0 TSRMLS_CC);

if (class_container.name == cl_name) { 

class_container.name = zend_strndup(cl_name, _len);

}                                     

class_container.name_length = _len;

INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \

}

#define INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) {                             

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.traits = NULL;         

class_container.num_traits = 0;       

class_container.trait_aliases = NULL; 

class_container.trait_precedences = NULL;

class_container.interfaces = NULL;     

class_container.get_iterator = NULL;   

class_container.iterator_funcs.funcs = NULL;

class_container.info.internal.module = NULL;

class_container.info.internal.builtin_functions = functions;

}

五、PHP_METHOD

PHP_METHOD(test,__construct);

PHP_METHOD(test,__destruct);

PHP_METHOD(test,setproperty);

PHP_METHOD(test,getproperty);

内核中的定义

#define PHP_METHOD  ZEND_METHOD

#define ZEND_METHOD(classname, name)  ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC

//等价于

void name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC )


六、zend_arg_info

typedef struct _zend_arg_info {

const char *name; //参数名称

zend_uint name_len;//长度

const char *class_name;  //所属类名

zend_uint class_name_len;  //类名长度

zend_bool array_type_hint;

zend_bool allow_null; //允许为空

zend_bool pass_by_reference;  //引用传值

zend_bool return_reference;  //引用返回

int required_num_args;  //参数个数

} zend_arg_info;

接受参数.那么就要执行 

ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0)

ZEND_ARG_INFO(0, url)

ZEND_END_ARG_INFO()


ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h

define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)      \

static const zend_arg_info name[] = {                                                                                                                                          \

{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },


ZEND_ARG_INFO(0,url)的定义如下

#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },

最终是这样的

static const zend_arg_info name[] = {

{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },

{ #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },

};

七、定义一个类

1、申明

static zend_class_entry *test_ce;

2、添加方法

const zend_function_entry test_methods[] = {

PHP_ME(test, __construct, test___construct_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)

PHP_ME(test, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)

PHP_ME(test, __toString, NULL, ZEND_ACC_PUBLIC)

PHP_ME(test, getMeta, NULL, ZEND_ACC_PUBLIC)

PHP_ME(test, setMeta, NULL, ZEND_ACC_PUBLIC)

{ NULL, NULL, NULL }

};

//ZEND_ACC_CTOR标示构造函数

//ZEND_ACC_DTOR标示析构函数


3、PHP_MINIT_FUNCTION中初始化

PHP_MINIT_FUNCTION(test)

{

/*定义一个temp class*/

zend_class_entry ce;

/*初始化这个class,第二个参数是class name, 第三个参数是class methods*/

INIT_CLASS_ENTRY(ce, "test", test_methods);

/*注册这个class到zend engine*/

test_ce = zend_register_internal_class(&ce TSRMLS_CC);

return SUCCESS;

}


4、定义参数

ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0)

ZEND_ARG_INFO(0, url)

ZEND_END_ARG_INFO()

5、具体方法

static PHP_METHOD(test, __construct) {

char *url;

int url_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url, &url_len, &age) == FAILURE) {

return;

}

zval *obj;

obj = getThis();

zend_update_property_stringl(test_ce, obj, "url", sizeof("url") -1, url, url_len TSRMLS_CC);

}

6、在PHP中访问

<?php

$c = new test('http://test.com');

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6435a43749282e4ff291fad89d79a04c.html