I've seen it a long time ago, I'll summarize it today.
One, create a class in PHP
Creating a simple class in PHP is like this:
<?php$obj = new Test ($url));? >
II. Structure of Zend_class_entry
Zend_class_entry is a struct defined in the kernel and is the infrastructure type of classes and objects in PHP.
struct _zend_class_entry {char type; Type: Zend_internal_class/zend_user_class char *name;//class name Zend_uint name_length; That is, sizeof (name)-1 struct _zend_class_entry *parent; The inherited parent class int refcount; Reference number Zend_bool constants_updated; Zend_uint Ce_flags; Zend_acc_implicit_abstract_class: Class exists abstract method//Zend_acc_explicit_abstract_class: Add the abstract keyword in front of the class name//Zend_a Cc_final_class//Zend_acc_interface HashTable function_table; Methods HashTable default_properties; Default property HashTable Properties_info; The property information HashTable the static variable HashTable *static_members of the default_static_members;//class itself; Type = = Zend_user_class, fetch &default_static_members; Type = = Zend_interal_class, set to null HashTable constants_table; The constant struct _zend_function_entry *builtin_functions;//method defines the entry union _zend_function *constructor; Union _zend_function *destructor; Union _zend_function *clone; /* Magic Method */ 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;//Iteration/* Class handle */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); /* Interface for class declaration */INT (*interface_gets_implemented) (Zend_class_entry *iface, Zend_class_entry *class_type TSRMLS_D C); /* Serialize callback function pointer */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_unseriali Ze_data *data tsrmls_dc); Zend_class_entry **interfaces; //class implements the interface Zend_uint num_interfaces; The number of interfaces implemented by the class char *filename; The storage file address of the class is the absolute address zend_uint Line_start; The start line of the class definition Zend_uint line_end; The end line of the class definition char *doc_comment; Zend_uint Doc_comment_len; struct _zend_module_entry *module; Module entry where class is located: EG (Current_module)};
Second, access control
Fn_flags delegates can be used when defining a method, Zend_property_info.flags can be used when defining a property, Ce_flags represents a//zend_acc_ctor when defining zend_class_entry Constructor mask, Zend_acc_dtor destructor mask//zend_acc_static STATIC function Mask//zend_acc_abstract ABSTRACT function Mask # define Zend_acc_static 0x01/* fn_flags, Zend_property_info.flags */#define ZEND_ACC_ABSTRACT 0x02/* FN_FL AGS */#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_CL 0x20/* ce_flags * * #define ZEND_ACC_FINAL_CLASS 0x40//ce_flags * #define ZEND_ACC_INTERFAC E 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_AC C_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_al Low_static 0x10000/* fn_flags */#define ZEND_ACC_SHADOW 0x20000//fn_flags */#define zend_acc_deprecated 0x40000/* fn_flags */#define ZEND_ACC_CLOSURE 0x100000//Fn_fla GS */#define Zend_acc_call_via_handler 0x200000/* fn_flags */
Iii. declaring and updating attributes in a class
Zend_api int zend_declare_class_constant (zend_class_entry *ce, const char *name, size_t name_length, Zval *value TSRMLS_D C); 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 TSRM LS_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 *V Alue 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 TSR MLS_DC); Zend_api void Zend_update_property_long (Zend_class_entry *scope, Zval *object, char *name, int name_length, Long value TSR MLS_DC); Zend_api void Zend_update_property_double (Zend_class_entry *scope, Zval *object, char *name, int name_length, double valu e 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 T SRMLS_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);
Add properties dynamically
#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)
Iv. 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.construc Tor = 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;}
Wu, Php_method
Php_method (test,__construct); Php_method (test,__destruct); Php_method (Test,setproperty); Php_method (Test,getproperty);
Definitions in the kernel
#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 r Eturn_v alue_used tsrmls_dc//equivalent to void name (int ht, zval *return_value, Zval **return_value_ptr, zval *this_ptr, int re Turn_v alue_used tsrmls_dc)
Liu, Zend_arg_info
typedef struct _ZEND_ARG_INFO { const char *name;//Parameter name zend_uint name_len;//length const char *class_name; belongs to the class name zend_uint Class_name_len; Class name length zend_bool array_type_hint; Zend_bool Allow_null; Allow for empty zend_bool pass_by_reference; Reference value Zend_bool return_reference; The reference returns int Required_num_args; Number of arguments} zend_arg_info;
Accept the parameters. Then we're going to execute
Zend_begin_arg_info (test___construct_arginfo, 0) zend_arg_info (0, URL) zend_end_arg_info ()
ZEND_BEGIN_ARG_INFO_EX 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},
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},
That's the end of it.
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},};
Vii. definition of a Class 1, declaration
Static Zend_class_entry *test_ce;
2. How to add
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-labeled constructor//zend_acc_dtor the destructor
3. Initialize in Php_minit_function
Php_minit_function (test) {/ * defines a temp class*/ zend_class_entry ce; /* Initialize this class, the second parameter is 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. Defining 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;< c5/>} zval *obj; obj = Getthis (); Zend_update_property_stringl (test_ce, obj, "url", sizeof ("url")-1, URL, Url_len tsrmls_cc);}
6. Access in PHP
<?php $c = new Test (' http://test.com ');? >
Articles that can be consulted
Http://www.phpinternalsbook.com/classes_objects/simple_classes.html
Object-oriented summary of deep PHP kernel