Skip to content

Latest commit

 

History

History
261 lines (196 loc) · 10.4 KB

09.md

File metadata and controls

261 lines (196 loc) · 10.4 KB

类与对像1

1,创建一个扩展

./ext_skel --extname=objects1

2,zend_class_entry结构

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 *static_members;
		HashTable constants_table;
		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 *_ _call;

		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 TSRMLS_DC);
		int (*interface_gets_implemented)
       		(zend_class_entry *iface, zend_class_entry *class_type 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;
};

3,类的定义

static zend_class_entry *hello_ce;  //申明类

/*=========================申明类的方法=======================*/
const zend_function_entry hello_methods[] = {
	PHP_ME(Hello, __construct, hello___construct_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) //构造函数申明		PHP_ME(Hello, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) //析构函数申明
	PHP_ME(Hello, __toString, NULL, ZEND_ACC_PUBLIC)
	PHP_ME(Hello, updateProperties, NULL, ZEND_ACC_PUBLIC)
	PHP_ME(Hello, addProperties, NULL, ZEND_ACC_PUBLIC)
	{ NULL, NULL, NULL }
};


/*==========================初始化类=======================================*/
PHP_MINIT_FUNCTION(objects1)
{
	/*定义一个temp class*/
	zend_class_entry ce;
	
	/*初始化这个class,第二个参数是class name, 第三个参数是class methods*/
	INIT_CLASS_ENTRY(ce, "Hello", hello_methods);

	/*注册这个class到zend engine*/
	/*This function also returns the final class entry, so it can be stored in the global variable declared above*/
	hello_ce = zend_register_internal_class(&ce TSRMLS_CC);
	
	return SUCCESS;
}


/*====================定义类的属性======================================*/
zend_declare_property_string(hello_ce, "name", sizeof("name") - 1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_long(hello_ce, "age", sizeof("age") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(hello_ce, "last_name", sizeof("last_name") -1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_null(hello_ce, "first_name", sizeof("first_name") -1, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_bool(hello_ce, "sex", sizeof("sex") -1, 1, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_double(hello_ce, "score", sizeof("score") -1, 12.50, ZEND_ACC_PUBLIC TSRMLS_CC);

/*====================更新属性值=======================================*/
zval *obj;
obj = getThis();
zend_update_property_string(hello_ce, obj, "name", sizeof("name") -1, "name-update" TSRMLS_CC);//更新属性值, $this->name = name
zend_update_property_long(hello_ce, obj, "age", sizeof("age") -1, 10 TSRMLS_CC); //this->age = age
zend_update_property_string(hello_ce, obj, "last_name", sizeof("last_name") -1, "leon-update" TSRMLS_CC);//this->last_name = "leon"
zend_update_property_null(hello_ce, obj, "first_name", sizeof("first_name") - 1 TSRMLS_CC); //this->first_name = null;
zend_update_property_bool(hello_ce, obj, "sex", sizeof("sex") -1, 0 TSRMLS_CC); //this->sex = true
zend_update_property_double(hello_ce, obj, "score", sizeof("score") -1, 15.50 TSRMLS_CC); //this->score = 12.50

/*==================动态添加属性=====================================*/
zval *obj;
obj = getThis();

/*add zval property*/
zval *arr;
MAKE_STD_ZVAL(arr);
array_init(arr);
add_assoc_string(arr, "e", "hello", 1);
add_index_string(arr, 1, "hello1111", 1);
add_property_zval_ex(obj, "persons", strlen("persons")+1, arr TSRMLS_CC);
Z_DELREF_P(arr);


/*add double property*/
add_property_double(obj, "d", 10.5);

/*add bool property*/
add_property_bool(obj, "b", 1);

/*add string property*/
char *str = "hello str";
add_property_string(obj, "str", str, 1);

/*add long property*/
add_property_long(obj, "l", 12);


/*==========================构造函数=========================*/
ZEND_BEGIN_ARG_INFO(hello___construct_arginfo, 0)
	ZEND_ARG_INFO(0, name)
	ZEND_ARG_INFO(0, age)
ZEND_END_ARG_INFO()

static PHP_METHOD(Hello, __construct) {
	char *name;
	int name_len;
	long age;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &age) == FAILURE) {
   	 return;
	}

	zval *obj;
	obj = getThis();

	zend_update_property_stringl(hello_ce, obj, "name", sizeof("name") -1, name, name_len TSRMLS_CC);//更新属性值, $this->name = name
	zend_update_property_long(hello_ce, obj, "age", sizeof("age") -1, age TSRMLS_CC); //this->age = age
}


/*=========================析构函数==========================*/
static PHP_METHOD(Hello,  __destruct) {
	php_printf("call __destruct function...\n");
}


/*========================toString========================*/
static PHP_METHOD(Hello, __toString) {
	RETURN_STRING("Hello Class\n", 1);
}

4,类的控制

//fn_flags代表可以在定义方法时使用,zend_property_info.flags代表可以在定义属性时使用,ce_flags代表在定义zend_class_entry时候可用
//ZEND_ACC_CTOR 构造函数掩码 , ZEND_ACC_DTOR  析构函数掩码
//ZEND_ACC_STATIC static函数掩码
//ZEND_ACC_ABSTRACT abstract函数掩码

#define ZEND_ACC_STATIC                     0x01     /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_ABSTRACT                   0x02     /* fn_flags */
#define ZEND_ACC_FINAL                      0x04     /* fn_flags */
#define ZEND_ACC_IMPLEMENTED_ABSTRACT       0x08     /* fn_flags */
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS    0x10     /* ce_flags */
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS    0x20     /* ce_flags */
#define ZEND_ACC_FINAL_CLASS                0x40     /* ce_flags */
#define ZEND_ACC_INTERFACE                  0x80     /* ce_flags */
#define ZEND_ACC_INTERACTIVE                0x10     /* fn_flags */
#define ZEND_ACC_PUBLIC                     0x100    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_PROTECTED                  0x200    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_PRIVATE                    0x400    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_PPP_MASK   (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
#define ZEND_ACC_CHANGED                    0x800    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_IMPLICIT_PUBLIC            0x1000   /* zend_property_info.flags; unused (1) */
#define ZEND_ACC_CTOR                       0x2000   /* fn_flags */      
#define ZEND_ACC_DTOR                       0x4000   /* fn_flags */     
#define ZEND_ACC_CLONE                      0x8000   /* fn_flags */
#define ZEND_ACC_ALLOW_STATIC               0x10000  /* fn_flags */
#define ZEND_ACC_SHADOW                     0x20000  /* fn_flags */
#define ZEND_ACC_DEPRECATED                 0x40000  /* fn_flags */
#define ZEND_ACC_CLOSURE                    0x100000 /* fn_flags */
#define ZEND_ACC_CALL_VIA_HANDLER           0x200000 /* fn_flags */

5,宏

#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_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;
}