PHP kernel research: HASH table and variable _ PHP Tutorial-php Tutorial

Source: Internet
Author: User
PHP kernel research: HASH tables and variables. In PHP, all data, regardless of variables, constants, classes, and attributes, are implemented using the Hash table. First, let's talk about the HASH table typedefstructbucket {ulongh; * Usedfornumericindexing * ui php hash table.

In PHP, all data, regardless of variables, constants, classes, and attributes, are implemented using the Hash table.

HASH table first

Typedef struct bucket {

Ulong h;/* Used for numeric indexing */

Uint nKeyLength; // key length

Void * pData; // point to the data pointer stored in Bucke

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 be last element */

} Bucket;

Typedef struct _ hashtable {

Uint nTableSize; // HashTable size

Uint nTableMask; // equal to nTableSize-1

Uint nNumOfElements; // number of objects

Ulong nNextFreeElement; // point to the next null element location nTableSize + 1

Bucket * pInternalPointer;/* Used for element traversal * // Save the pointer for the current traversal

Bucket * pListHead; // header element pointer

Bucket * pListTail; // tail element pointer

Bucket ** arBuckets; // stores hash array data

Dtor_func_t pDestructor; // similar to Destructor

Zend_bool persistent; // which method is used to allocate the memory space? PHP manages the memory in a unified manner.

Unsigned char nApplyCount; // The number of times the current hash bucket is accessed and whether data has been traversed to prevent infinite recursive loops

Zend_bool bApplyProtection;

# If ZEND_DEBUG

Int inconsistent;

# Endif

} HashTable;

Let's talk about the HASH table initialization function.

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) {// The n I ++;} ht-> nTableSize = 1 <I; // The HASH bucket has the I power of 2 and I = 3. the minimum nTableSize is 8.

}

// To improve the computing efficiency, the system automatically adjusts nTableSize to the integer power of 2, which is not less than nTableSize. That is to say, if you specify a nTableSize not the integer power 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. it is called when HashTable is added, deleted, or changed.

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 to allocate memory to the Bucket. Otherwise, use the PHP memory allocation function.

Ht-> nApplyCount = 0;

Ht-> bApplyProtection = 1;

/* Uses ecalloc () so that Bucket * = NULL */

If (persistent) {// memory allocation mode of the operating system itself. the memory is automatically initialized to 0 after calloc is allocated.

Tmp = (Bucket **) calloc (ht-> nTableSize, sizeof (Bucket *));

If (! Tmp ){

Return FAILURE;

}

Ht-> arBuckets = tmp;

} Else {// use the PHP memory management mechanism to allocate memory

Tmp = (Bucket **) ecalloc_rel (ht-> nTableSize, sizeof (Bucket *));

If (tmp ){

Ht-> arBuckets = tmp;

}

}

// Automatically apply for a piece of memory for arBuckets. the memory size is equal to nTableSize.

Return SUCCESS;

}

When reading the source code, we often see macros such as EG, PG, and CG.

CG is short for compile_global

EG is short for excutor_global

G indicates the global variable.

Let's take the macro example.

# Ifdef ZTS

# Define EG (v) TSRMG (executor_globals_id, zend_executor_globals *, v)

# Else

# Define EG (v) (executor_globals.v)

Extern ZEND_API zend_executor_globals executor_globals;

# Endif

It's just a macro that gets global variables.

Let's look at the structure zend_executor_globals.

Defined in/Zend/zend. h

Typedef struct _ zend_executor_globals;

Is an alias for _ zend_executor_globals

Find it in the same file

All the local variables, global variables, functions, and classes in PHP are defined here.

Struct _ zend_executor_globals {

Zval ** return_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 * comment lout;

Int error_reporting;

Int orig_error_reporting;

Int exit_status;

Zend_op_array * active_op_array;

HashTable * function_table;/* function symbol table * // function table

HashTable * class_table;/* class table * // class table

HashTable * zend_constants;/* constants table * // constant table

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_direves VES;

HashTable * modified_ini_directives;

Zend_objects_store objects_store;

Zval * exception, * prev_exception;

Zend_op * opline_before_exception;

Zend_op prediction_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];

};

Let's take a look at it. I will discuss it later,

The most basic unit variable in PHP:

Defining a variable in PHP is much simpler.

For example

$ A = 1;

?>

However, in the kernel, it is implemented using a zval struct.

For example, the above defined variables execute the following code in the kernel:

Zval * val;

MAKE_STD_ZVAL (val); // apply for a piece of memory

ZVAL_STRING (val, "hello", 1); // use ZVAL_STRING to set its value to "hello"

ZEND_SET_SYMBOL (EG (active_symbol_table), "a", val); // add the val pointer to the symbol table.

Macro MAKE_STD_ZVAL is defined as follows

# Define MAKE_STD_ZVAL (zv )\

ALLOC_ZVAL (zv); \ // It is equivalent to (p) = (type *) emalloc (sizeof (type ))

INIT_PZVAL (zv );

INIT_PZVAL is defined in

# Define INIT_PZVAL (z) \ it can be seen that it is an initialization parameter

(Z)-> refcount _ gc = 1 ;\

(Z)-> is_ref _ gc = 0;

So what is zval?

In zend/zend. h

Typedef struct _ zval_struct zval; // It is the alias of _ zval_struct.

_ Zval_struct:

Typedef union _ zvalue_value {

Long lval; // save data of the long type

Double dval; // save data of the double type

Struct {

Char * val; // The true value here

Int len; // return the length here

} Str;

HashTable * ht;

Zend_object_value obj; // This is an object

} Zvalue_value;

Struct _ zval_struct {

Zvalue_value value; // saved value

Zend_uint refcount _ gc; // if the number of times referenced is 1, it is used only by itself. if the number is greater than 1, it is referenced by other variables in the form.

Zend_uchar type; // data type. This is why PHP is weak.

Zend_uchar is_ref _ gc; // indicates whether it is referenced.

};

If it is not clear enough, we will try to use C to create a PHP variable.

Here we need an extension. If PHP uses the C extension module, we will not talk about it here.

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; // non-reference variable

Value-> refcount _ gc = 1; // only the user can reference the number of times.

Value-> type = IS_STRING; // The type is a string.

Value-> value. str. val = s; // value

Value-> value. str. len = strlen (s); // length

ZEND_SET_SYMBOL (EG (active_symbol_table), "a", value );

}

The functions of the third and fourth rows are the same as those of MAKE_STD_ZVAL, and the memory space is allocated to the value.

Line 5-9 has the same effect as ZVAL_STRING,

The last line is to create a variable named $ a in PHP and add it to the local Hash table ..

In this way, in PHP

Test_siren (1 );

Echo $;

?>

The output "create a php variable"

OK,

Success

Note: I want to let everyone see the process of creating variables in PHP to create variables in the form of C,

We do not recommend this.

You must use the internal memory management mechanism of PHP to allocate and process the memory.

Http://www.bkjia.com/PHPjc/477783.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/477783.htmlTechArticlePHP HASH table in PHP, all data regardless of variables, constants, classes, attributes are implemented using Hash table. first let's talk about the HASH table typedef struct bucket {ulong h;/* Used for numeric indexing */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.