您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 娄底分类信息网,免费分类信息发布

深入PHP内核之面向对象小结

2024/5/30 14:56:05发布30次查看
深入php内核之面向对象总结
很久以前看过的,今天总结一下
一、php中创建一个类在php中创建一个简单的类是这样的:

二、zend_class_entry结构zend_class_entry是内核中定义的一个结构体,是php中类与对象的基础结构类型。
struct _zend_class_entry { char type; // 类型:zend_internal_class / zend_user_class char *name;// 类名称 zend_uint name_length; // 即sizeof(name) - 1 struct _zend_class_entry *parent; // 继承的父类 int refcount; // 引用数 zend_bool constants_updated; zend_uint ce_flags; // zend_acc_implicit_abstract_class: 类存在abstract方法 // zend_acc_explicit_abstract_class: 在类名称前加了abstract关键字 // zend_acc_final_class // zend_acc_interface hashtable function_table; // 方法 hashtable default_properties; // 默认属性 hashtable properties_info; // 属性信息 hashtable default_static_members;// 类本身所具有的静态变量 hashtable *static_members; // type == zend_user_class时,取&default_static_members; // type == zend_interal_class时,设为null 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 *__unset; union _zend_function *__isset; union _zend_function *__call; union _zend_function *__tostring; union _zend_function *serialize_func; union _zend_function *unserialize_func; zend_class_iterator_funcs iterator_funcs;// 迭代 /* 类句柄 */ zend_object_value (*create_object)(zend_class_entry *class_type tsrmls_dc); zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, intby_ref tsrmls_dc); /* 类声明的接口 */ int(*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type tsrmls_dc); /* 序列化回调函数指针 */ int(*serialize)(zval *object, unsignedchar**buffer, zend_uint *buf_len, zend_serialize_data *data tsrmls_dc); int(*unserialize)(zval **object, zend_class_entry *ce, constunsignedchar*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; // 类所在的模块入口:eg(current_module)};
二、访问控制//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 */
三、申明和更新类中的属性zend_api int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value tsrmls_dc); zend_api int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length tsrmls_dc); zend_api int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, long value tsrmls_dc); zend_api int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value tsrmls_dc); zend_api int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value tsrmls_dc); zend_api int zend_declare_class_constant_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_length tsrmls_dc); zend_api int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value tsrmls_dc); zend_api void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length tsrmls_dc);zend_api void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value tsrmls_dc);zend_api void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value tsrmls_dc);zend_api void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value tsrmls_dc);zend_api void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value tsrmls_dc);zend_api void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value, int value_length tsrmls_dc);zend_api int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length tsrmls_dc);zend_api int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value tsrmls_dc);zend_api int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value tsrmls_dc);zend_api int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value tsrmls_dc);zend_api int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, const char *value tsrmls_dc);zend_api int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, const char *value, int value_length tsrmls_dc);
动态添加属性
#define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key)+1, __n tsrmls_cc)#define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) + 1 tsrmls_cc)#define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key)+1, __b tsrmls_cc)#define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key)+1, __r tsrmls_cc)#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key)+1, __d tsrmls_cc)#define add_property_string(__arg, __key, __str, __duplicate) add_property_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate tsrmls_cc)#define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate tsrmls_cc)#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key)+1, __value tsrmls_cc)
四、一些其它的宏#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;}
五、php_methodphp_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_infotypedef 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中访问
可以参考的文章
http://www.phpinternalsbook.com/classes_objects/simple_classes.html
娄底分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录