PHP Variable components:
Variable name: The PHP language variable name starts with $ + English/Underscore, can contain numbers, underscores, letters, case-sensitive. PHP also supports complex variables, such as $ $A, which increases the dynamic nature of PHP.
Type: PHP is a weakly typed language and can assign values of any type.
Content: There can only be one value at a time.
There are 8 types of data in the PHP language, which are divided into three main categories:
1. Scalar type: boolean,integer,float,string;
2. Compound type: object,array;
3. Special type: Null,resource;
PHP as a weak type language, in the implementation of all variables are zval to store data through the structure, not only contains the value of variables, but also contains the type of variable, is the core of PHP weak type.
ZVAL Data structure:
struct _zval_struct{
zvalue_value value; The value of the stored variable
zend_unint refcount_gc//reference count
Zend_char is_ref_gc; Whether it is a reference
Zend_char type; Type of storage variable
}
Zvalue_value is not a struct, and is implemented in order to conserve the union of memory use, because at the same time the variable can only represent one type. Its prototype:
typedef Union _zvalue_value{
long lval;
Double dval;
struct {
char *val;
int Len; The length of the string is
}str;
HashTable *ht; Save array
zend_object_value obj; Object
}zvalue_value;
Hash table:
Many implementations of PHP are based on hash tables: The scope of variables, function tables, properties of classes, methods, etc., many of the data inside the Zend engine are stored in the hash table.
The PHP array uses a hash table to store the associated data, which uses two data structures hashtable and bucket:
HashTable:
typedef struct _HASHTABLE {
uint ntablesize; The size of the hash bucket, with a minimum of 8, increases by 2x.
UINT Ntablemask; NTableSize-1, optimization of index value
uint nnumofelements; The number of elements that are currently in the hash Bucket, and the count () function returns the value
ulong nnextfreeelement;///The position of the next numeric index
Bucket *pinternalpointer; The current traversal pointer (foreach is one of the reasons for fast)
Bucket *plisthead; Storage array header element pointer
Bucket *plisttail; Storage array tail element pointer
Bucket **arbuckets; Storage hash array
dtor_func_t pdestructor; The callback function that is executed when the element is deleted, for the release of the resource
zend_bool persistent; The way of bucket memory allocation is pointed out. If Persisient is true, use the memory allocation
function of the operating system itself to allocate memory for bucket, otherwise use
the memory allocation function of PHP.
unsigned char napplycount//mark the number of times the current hash bucket is recursively accessed (prevent multiple recursion)
Zend_bool bapplyprotection;// Mark current Hash bucket allow multiple access is not allowed, the maximum can only be recursive 3 times
#if zend_debug
int inconsistent;
#endif
} HashTable;
The expansion of capacity in the Hashtable is always adjusted to an integer that is close to the initial size of 2. Because:
In the slot selection, use the & operation instead of modulo, because it is relative to the consumption of the modulo operation and the operation of the bitwise and much larger. The role of mask is to map the hash value to the range of indexes that the slot can store. For example: The index value of a key is 21, the hash table size is 8, then the mask is 7, then the binary representation is: 10101 & 111 = 101 is the decimal 5. Because 2 of the whole number of the second-1 binary is special: The next n-bit value is 1, so it is easier to map the value, if the normal number of binary and then affect the result of the hash value. Then the average distribution of the values computed by the hash function may have an effect.
Bucket
typedef struct BUCKET {
ulong H; A hash value for char *key, or a user-specified numeric index value
uint Nkeylength; The length of the hash keyword, if the array index is a number, this value is 0
void *pdata; Point to value, which is usually a copy of the user's data and, if it is pointer data, point to pdataptr
void *pdataptr; In the case of pointer data, this value points to true value, while above pdata points to the value
struct bucket *plistnext; The next element of the entire hash table
struct bucket *plistlast; The entire hash table the previous element of the element
struct bucket *pnext; The next element stored in the same hash bucket
struct bucket *plast; The last element of the same hash bucket
//holds the key string for the current value, which can only be defined at the end, to implement the variable-length structure
char arkey[1];
A hash value is stored in the bucket, not a hash index.
The last field in the structure above is used to hold the string of the key, which is declared to be an array of only one character, in fact here is a long, variable-length structure, the main purpose is to increase flexibility. The following code to request space when inserting new elements into a hash table
p = (Bucket *) pemalloc (sizeof (Bucket)-1 + nkeylength, ht->persistent);
if (!p) {return
failure;
}
memcpy (P->arkey, Arkey, nkeylength);
Insert Process Diagram
Hashing algorithm
The hash function in PHP is implemented using the DJBX33A algorithm.
Object:
PHP objects are stored using data structure zend_object_value;