In-depth PHP kernel object-oriented summary, php kernel object-oriented. In-depth PHP kernel object-oriented summary, php kernel object-oriented 1. create a class in PHP and create a simple class in PHP :? Php $ objnewtest ($ url ));? II. zend_cl in-depth PHP kernel object-oriented summary, php kernel object-oriented summary
1. create a class in PHP
Create a simple class in PHP as follows:
II. zend_class_entry structure
Zend_class_entry is a struct defined in the kernel and is the basic structure type of classes and objects in PHP.
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;};
II. access control
// Fn_flags indicates that the method can be used when defining the method, zend_property_info.flags indicates that the attribute can be used when defining the attribute, and ce_flags indicates that zend_class_entry is available when defining the ZEND_ACC_CTOR constructor mask, ZEND_ACC_DTOR destructor mask // ZEND_ACC_STATIC static function mask // ZEND_ACC_ABSTRACT function mask # define ZEND_ACC_STATIC 0x01/* fn_flags, optional */# define ZEND_ACC_ABSTRACT 0x02/* fn_flags */# define ZEND_ACC_FINAL 0x04/* fn_flags */# define limit 0x08/* fn_flags */# define limit 0 x 10/* ce_flags */# define defaults 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 0 0x100/* fn_flags, required */# define limit 0x200/* fn_flags, limit */# define ZEND_ACC_PRIVATE 0x400/* fn_flags, limit */# define limit (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 0 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 limit 0 x 10000/* fn_flags */# define ZEND_ACC_SHADOW 0x20000/* fn_flags */# define defaults 0x40000/* fn_flags */# define ZEND_ACC_CLOSURE 0x100000/* fn_flags */# define ZEND_ACC_CALL_VIA_HANDLER 0x200000/* fn_flags */
3. declare and update attributes in the class
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);
Dynamically add attributes
#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)
4. some other macros
#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;}
V. PHP_METHOD
PHP_METHOD(test,__construct);PHP_METHOD(test,__destruct);PHP_METHOD(test,setproperty);PHP_METHOD(test,getproperty);
Definition in the kernel
# Define PHP_METHOD ZEND_METHOD # define ZEND_METHOD (classname, name) limit (ZEND_MN (classname #### name) # define limit int ht, zval * return_value, zval ** return_value_ptr, zval * this_ptr, int return_v alue_used TSRMLS_DC // equivalent to void name (int ht, zval * return_value, zval ** values, zval * this_ptr, int return_v alue_used TSRMLS_DC)
VI. zend_arg_info
Typedef struct _ zend_arg_info {const char * name; // parameter name zend_uint name_len; // length const char * class_name; // class name zend_uint class_name_len; // the length of the class name zend_bool array_type_hint; zend_bool allow_null; // zend_bool pass_by_reference is allowed; // the reference value zend_bool return_reference is returned. // int limit is returned for reference; // number of parameters} zend_arg_info;
Accept the parameter. then execute
ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0) ZEND_ARG_INFO(0, url)ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX is defined in 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 },
The ZEND_ARG_INFO (0, url) is defined as follows:
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
In the end
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 },};
7. define a class 1. Declaration
static zend_class_entry *test_ce;
2. Add methods
Const login test_methods [] = {PHP_ME (test, _ construct, test ___ construct_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME (test, _ destruct, NULL, ZEND_ACC_PUBLIC | login) 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 constructor // ZEND_ACC_DTOR indicates the destructor
3. PHP_MINIT_FUNCTION initialization
PHP_MINIT_FUNCTION (test) {/* defines a temp class */zend_class_entry ce;/* initializes this class. The second parameter is the class name, the third parameter is class methods */INIT_CLASS_ENTRY (ce, "test", test_methods);/* register this class to zend engine */test_ce = zend_register_internal_class (& ce TSRMLS_CC ); return SUCCESS ;}
4. define parameters
ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0) ZEND_ARG_INFO(0, url)ZEND_END_ARG_INFO()
5. specific methods
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. access in PHP
Tip 1: create a class in PHP and create a simple class in PHP :? Php $ obj = new test ($ url ));? II. zend_cl...