PHP Kernel research: Hash table and Variable _php tutorial

Source: Internet
Author: User
Tags zend
PHP hash table in PHP, all the data regardless of variables, constants, classes, attributes are used in the hash table to achieve. First talk about hash table typedef struct Bucket {ULONG H;/* Used for numeric indexing */uint nkeylength;//key length void *pdata;//Point Buc Ke saves the data pointer void *pdataptr; Pointer data struct bucket *plistnext; Next element pointer struct bucket *plistlast;//previous element pointer struct bucket *pnext; struct bucket *plast; Char arkey[1]; /* must is last element */} Bucket; typedef struct _HASHTABLE {UINT ntablesize;//hashtable size uint ntablemask;//equals nTableSize-1 uint nnumofelements;//number of objects ULONG nnextfreeelement;//refers to the downward an empty element position ntablesize+1 Bucket *pinternalpointer; /* Used for element traversal *///Save the currently traversed pointer bucket *plisthead;//head element pointer bucket *plisttail;//tail element pointer bucket **arbuckets;//storage ha SH array Data dtor_func_t pdestructor;//is similar to a destructor Zend_bool persistent;//which method allocates memory space PHP Unified management memory or with normal malloc unsigned char napplycount;//the number of times the current hash bucket is accessed, whether to traverse the data, to prevent infinite recursive loop zend_bool bapplyprotection; #if Zend_debug int inconsistent; #endif} HashTable; We combine the hash table initialization function to Zend_api int _zend_hash_init (HashTable *ht, uint nSiZe, hash_func_t phashfunction, dtor_func_t pdestructor, Zend_bool persistent zend_file_line_dc) {UINT i = 3; Bucket **tmp; Set_inconsistent (HT_OK); if (nSize >= 0x80000000) {//hash table size greater than 0x8 is initialized to 0x8/* Prevent overflow */ht->ntablesize = 0x80000000;} else {while ((1U << i) < nSize) {//adjusted to 2 N-th square i++;} Ht->ntablesize = 1 << i;//hash bucket size is 2 i i=3, ntablesize minimum is 8}//To improve computational efficiency, the system automatically adjusts the ntablesize to a minimum of no less than ntab Lesize 2 of the whole number of square. That is, if you specify a ntablesize that is not an integer of 2 when initializing Hashtable, the system will automatically adjust the value of ntablesize Ht->ntablemask = ht->ntablesize-1; Ht->pdestructor = pdestructor;//A function pointer, when hashtable occurs increment, delete, change call ht->arbuckets = NULL; Ht->plisthead = NULL; Ht->plisttail = NULL; ht->nnumofelements = 0; ht->nnextfreeelement = 0; Ht->pinternalpointer = NULL; Ht->persistent = persistent;//If Persisient is true, use the memory allocation function of the operating system itself to allocate memory for buckets, otherwise use PHP's memory allocation function Ht->napplycount = 0; Ht->bapplyprotection = 1; /* Uses Ecalloc () so bucket* = = NULL */if (persistent) {//The operating system itself allocates memory by memory allocation, Calloc automatically initialized to 0 tmp = (Bucket * *) cal after allocating memory) LOC (ht->ntablesize, sizeof (Bucket *)); if (!tmp) {return FAILURE;} ht->arbuckets = tmp; } else {//allocates memory TMP = (bucket * *) Ecalloc_rel (ht->ntablesize, sizeof (bucket *)) with PHP's memory management mechanism; if (TMP) {ht->arbuckets = tmp; }}//automatically request a piece of memory to Arbuckets, the memory size is equal to ntablesize return SUCCESS; In reading the source code, often see EG,PG,CG such a macro CG is Compile_global shorthand EG is excutor_global shorthand g is the meaning of global variables we take EG macro as an example #ifdef ZTS # define EG (v) TSR MG (executor_globals_id, zend_executor_globals *, v) #eLSE # define EG (v) (EXECUTOR_GLOBALS.V) extern zend_api zend_executor_globals executor_globals; #endif is simply a macro that gets global variables so let's see zend_executor_globals this struct defines typedef struct _ZEND_EXECUTOR_GLOBALS zend_ in/zend/zend.h Executor_globals; It's a _zend_executor_globals alias. Find it in the same file all local variables in PHP, global variables, functions, and hash tables of classes are defined here as struct _zend_executor_globals {zval **retur N_value_ptr_ptr; Zval Uninitialized_zval; Zval *uninitialized_zval_ptr; Zval Error_zval; Zval *error_zval_ptr; Zend_ptr_stack Arg_types_stack; /* Symbol Table Cache */HashTable *symtable_cache[symtable_cache_size]; HashTable **symtable_cache_limit; HashTable **symtable_cache_ptr; Zend_op **opline_ptr; HashTable *active_symbol_table; local variable HashTable symbol_table; /* Main Symbol Table *////global variable HashTable included_files; /* files already included *///include file jmp_buf *bailout; int error_reporting; int orig_error_reporting; int exit_status; Zend_op_array *active_op_array; HashTable *function_table; /* Function Symbol Table *//Functions Table HashtAble *class_table; /* Class Table *//HashTable *zend_constants; /* Constants Table *///Chang zend_class_entry *scope; Zend_class_entry *called_scope; /* Scope of the Calling class */Zval *this; Long precision; int ticks_count; Zend_bool in_execution; HashTable *in_autoload; Zend_function *autoload_func; Zend_bool Full_tables_cleanup; /* For extended information support */Zend_bool no_extensions; #ifdef Zend_win32 Zend_bool timed_out; Osversioninfoex Windows_version_info; #endif HashTable regular_list; HashTable persistent_list; Zend_vm_stack Argument_stack; int user_error_handler_error_reporting; Zval *user_error_handler; Zval *user_exception_handler; Zend_stack user_error_handlers_error_reporting; Zend_ptr_stack user_error_handlers; Zend_ptr_stack user_exception_handlers; zend_error_handling_t error_handling; Zend_class_entry *exception_class; /* Timeout support */int timeout_seconds; int lambda_count; HashTable *ini_directives; HashTable *modified_ini_directives; Zend_objects_Store Objects_store; Zval *exception, *prev_exception; Zend_op *opline_before_exception; Zend_op Exception_op[3]; struct _zend_execute_data *current_execute_data; struct _zend_module_entry *current_module; Zend_property_info Std_property_info; Zend_bool active; void *SAVED_FPU_CW; void *reserved[zend_max_reserved_resources]; }; Here is a simple look, later when the use of the time to elaborate, PHP, the most basic unit variables: in PHP to define a variable is simple as But in the kernel it is implemented with a zval struct, as defined above the variables in the kernel executed the following code Zval *val; Make_std_zval (Val); Request a piece of memory Zval_string (val, "Hello", 1);//set its value with zval_string to "Hello" Zend_set_symbol (EG (active_symbol_table), "a", Val) );//Add Val pointer to the symbol table inside the macro make_std_zval is defined as follows #define MAKE_STD_ZVAL (ZV) \ Alloc_zval (ZV); \//It is ultimately equal to (p) = (type *) emalloc (sizeof (type)) Init_pzval (ZV); Init_pzval is defined in #define INIT_PZVAL (z) \ To see that it is an initialization parameter (z)->refcount__gc = 1; \ (z)->is_ref__gc = 0; So what is zval in the zend/zend.h inside typedef struct _ZVAL_STRUCT zval; Originally it was _zval_struct alias _zval_struct defined as follows typedef union _ZVALUE_VALUE {Long lval;//save long type of data double dval;//Save double type The data struct {char *val;//real value here int len;//Here Returns the length} str; HashTable *ht; Zend_object_value obj; This is an object} Zvalue_value; struct _zval_struct {zvalue_value value;//The saved value zend_uint the number of times refcount__gc;//is referenced if 1 is used only by itself if greater than 1 is referenced by other variables in the form of &. Zen D_uchar type; Data type This is why PHP is a weak type of reason Zend_uchar is_ref__gc; Indicates whether it is a reference}; If it's not clear enough. So let's do the actual combat. Using C to create a PHP variable here requires an extension, PHP if you use the C extension module hereNot to mention the key code php_function (Test_siren) {zval *value; char *s= "Create a PHP variable"; value= (zval*) malloc (sizeof (zval)); memset (value,0,sizeof (value)); value->is_ref__gc=0; A non-reference variable value->refcount__gc=1;//The number of references only to its own value->type=is_string;//type is the string value->value.str.val=s;//value value- >value.str.len=strlen (s);//Length Zend_set_symbol (EG (active_symbol_table), "a", value); The third and fourth rows function the same as the Make_std_zval, and the 第5-9 row for value allocates memory space is the same as zval_string, and the last line is to create a variable named $ A in PHP. And added to the local hash table. It's in PHP. Will output "Create a PHP variable" OK, done, I was to let you see the process of creating variables within PHP to create variables in the form of C, it is definitely not recommended to do so. It is important to allocate and process memory using the internal memory management mechanism of PHP.

http://www.bkjia.com/PHPjc/477783.html www.bkjia.com true http://www.bkjia.com/PHPjc/477783.html techarticle php hash table in PHP, all the data regardless of the variables, constants, classes, attributes are used in the hash table to achieve. Let's talk about hash table. typedef struct BUCKET {ULONG H;/* used for numeric indexin G */UI ...

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.