PHP core technologies and best practices assign values to variables in PHP extensions

Source: Internet
Author: User
PHP core technology and best practices assign values to variables in PHP extensions read this section. if you do not know the structure of variables in PHP, go to: variables in the PHP kernel.

The function of a variable is to store data. because a variable in PHP not only saves the value but also the type, it must not only assign values to the variable, but also set the type for the variable.

1) long integer (integer) type variable: all integers in the PHP kernel are long ), the value is stored in the lval field in the consortium value of the zval structure of the PHP variable mentioned earlier. the corresponding type is IS_LONG. the code for assigning values is as follows:

Zval * new_var;

MAKE_STD_ZVAL (new_var );

New_var-> value. lval = 12;

New_var-> type = IS_LONG;

However, ZVAL_LONG macro assignment is recommended for compatibility purposes:

Zval * new_var;

MAKE_STD_ZVAL (new_var );

ZVAL_LONG (new_var, 12 );

The above example has the same effect as the code;

2) double precision (floating point number) type variable: the difference between the value assignment of the same long integer type is only in the variable type IS_DOUBLE, ZVAL_DOUBLE (new_var, 12.56 );

3) string type variable: in addition to saving the value of the string, you also need to save the length of the string (provided to functions such as strlen ). The string value is stored in the val field in the str structure of the value consortium of the zval structure, and the string length is stored in the len field of the str structure, and the corresponding type is set to IS_STRING; in addition, it is worth noting that the internal block used to save the string value should be applied using the ZEND Engine memory management function to avoid self-managing the memory and making the ZEND Engine easier to process, the assignment code is as follows:

Zval * new_var;

Char * str = "this is n new string variable ";

MAKE_STD_ZVAL (new_var );

New_var-> value. str. len = strlen (str );

New_var-> value. str. val = estrdup (str); // estrdup is the memory management function of the ZEND Engine.

New_var-> type = IS_STRING;

Use the ZEND_STRING macro to assign values: ZVAL_STRING (new_var, str, 1); the third parameter specifies whether the string needs to be copied (using the ZEND Engine memory management function). when it is set to 1, the two parameters are copied to the string. when the value is set to 0, the val field is directly directed to the string pointed to by the two parameters (which can be understood as a reference value ).

If you only want to assign values to a part of the string or the length of the string that you already know, you can use the macro ZEND_STRINGL (zval, string, length, duplicate) to complete this task. the parameter length is the length of the specified string, ZVAL_STRINGL macro is faster than ZVAL_STRING macro. its definition is as follows:

# Define ZVAL_STRINGL (z, s, l, duplicate ){\

Char * _ s = (s); int _ l = l ;\

(Z)-> value. str. len = _ l ;\

(Z)-> value. str. val = (duplicate? Estrndup (_ s, _ l): _ s );\

(Z)-> type = IS_STRING ;\

}

From the definition, we can see that the length of the string (len field) is directly set to the value of the length parameter, so strlen () is no longer used to calculate the length of the string, to create an empty string, set its length to 0 and use empty_string as the string value.

New_var-> value. str. len = 0;

New_var-> value. str. val = empty_string;

New_var-> type = IS_STRING; or use the ZVAL_EMPTY_STRING macro to complete:

ZVAL_EMPTY_STRING (new_string); // The parameter is not missing here. it is determined that it is not ZVAL_EMPTY_STRING (new_var, new_string );?

4) Boolean variables: values of the Boolean type are similar to values of the integer type. The difference is that the field of the data type is set to IS_BOOL, and the value of the lval field can only be 0 or 1, ZVAL_BOOL macro code: ZVAL_BOOL (new_var, 1 );

5) array type variables: arrays play an important role in PHP. PHP is powerful because of the flexibility of arrays. in the kernel, arrays are stored using hash tables (HashTable ); when assigning an array to a variable, create a HashTable and save it in zval. in the ht field of the val container, the Zend Engine provides a simple interface array_init () to complete this task. the code is as follows:

Zval * new_var;

MAKE_STD_ZVAL (new_var );

Array_init (new_array );

The above code is equivalent

After creating an empty array, you can add elements to it. parallel line iron APIs are available. The following lists all APIs that can be used (SUCCESS is returned when successful, and FAILURE is returned when failed):

APIs for associating arrays:

Add_assoc_long (zval * array, char * key, long n); // equivalent to $ array ["key"] = 10;

Add_assoc_unset (zval * array, char * key); // $ array ["key"] = NULL;

Add_assoc_bool (zval * array, char * key, int B );

Add_assoc_resource (zval * array, char * key, int r );

Add_assoc_double (zval * array, char * key, double d );

Add_assoc_string (zval * array, char * key, char * str, int duplicate); // $ array ["key"] = "string ";

Add_assoc_stringl (zval * array, char * key, char * str, uinit length, int duplicate); // add a string of the specified length

Add_assoc_zval (zval * array, char * key, zval * value); // add a zval structure, which is useful when adding data such as an array, object, or stream, equivalent to $ array ["key"] = $ value;

Index array API: the index array is similar to the associated array. The difference is whether the subscript is a string or an integer, therefore, replacing all the char * keys in the prototype with unit idx is the index array API and will not be listed.

The API mentioned above is just an abstract HashTable API function. you can also directly use the HashTable API function for operations. for example, you can add an element to the array sk and use the zend_hash_update () function for operations. Example of adding an element to an array using API:

Zval array, element;

Char * key = "key for search ";

Char * value = "value_for_element ";

MAKE_STD_ZVAL (array );

MAKE_STD_ZVAL (element );

Array_init (array );

ZVAL_STRING (element, value, 1 );

Add_assoc_zval (array, key, element );

6) object type variable: before explaining how variables assign values to object types, you must first understand the relationship between PHP Objects and arrays: objects can be converted into arrays (this process is irreversible, because the object's functions will be lost), the object's attributes and arrays can be converted to each other. Should object functions be stored in a HashTable? This problem should be solved when you understand the functions in the PHP kernel.

The API code for creating an object is as follows:

Zval * new_object;

MAKE_STD_ZVAL (new_object );

If (object_init (new_object )! = SUCCESS ){

RETURN_NULL ();

}

The Zend Engine adds attributes to an object using the following APIs:

Add_property_long (zval * object, char

Key, long l );

Object, char * key );

Add_property_bool (zval * object, char * key, int B );

Add_property_resource (zval * object, char * key, long r );

Add_property_double (zval * object, char * key, double d );

Add_property_string (zval * object, char * key, char * str, int duplicate );

Add_property_stringl (zval * object, char * key, char * str, uint length, int duplicate );

Add_property_zval (zval * object, char * key, zval * container );

For example, add an attribute named "name" as a string as follows:

Zval * new_object;

MAKE_STD_ZVAL (new_object );

If (object_init (new_object )! = SUCCESS ){

RETURN_NULL ();

}

Add_property_string (new_object, "name", "James", 1 );

7) resource type variables: creating a resource type variable is more cumbersome than creating other types of variables. Strictly speaking, a resource is not a data type, it is an abstraction that can maintain any data type (like pointers in C ). All resources are saved in a Zend internal resource list. each resource in the list has a pointer to the actual data. if you know enough about the PHP kernel, you can directly access these resources. However, we recommend that you use APIs provided by the Zend Engine to access these resources for compatibility and security.

When a resource loses all references, the corresponding destructor is triggered, which is provided by the resource, the reason is that the zend Engine cannot manage the actual data of resources. to prevent memory leakage, you must provide the destructor to release the memory.

Database connections and file operators are PHP resource types. you can also save custom data structures and other types of data as resource types.

The zend_register_list_destructors_ex () function can be used to register a resource variable destructor. This function returns a resource handle, which is used to associate resources with resource destructor, the following is the definition of the zend_register_list_destructors_ex () function:

ZEND_API int_zend_register_list_destructors_ex (rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char * type_name, int module_number); the parameters are described as follows:

Ld: destructor of common resources,

Pld: destructor of persistent resources,

Type_name: specifies a name for the resource. it is a good habit to name a resource type in PHP. you can obtain the name of the resource when calling var_dump ($ resource.

Module_number: it is automatically defined in the module's PHP_MINIT_FUNCTION function, so it can be ignored.

Ld and pld must provide at least one, and another destructor can be set to NULL.

The prototype of the resource destructor must be defined as follows: void resource_destruction_handler (zend_rsrc_entry * rsrc TSRMLS_DC );

The rsrc parameter is a pointer to the zend_rsrc_list_entry struct:

Typedef struct _ zend_rsrc_list_entry {

Void * ptr; // the address used to save the real data of the resource. Generally, the memory pointed to by the ptr field is released in the destructor.

Int type;

Int refcount;

} Zend_rsrc_list_entry;

For example, define a linked list data structure as follows:

Typedef struct _ ListNode {

Struct _ ListNode * next;

Void * data;

} ListNode;

The resource variable then saves the head pointer of the linked list. The Destructor can be written as follows:

Void list_destroy_handler (zend_rsrc_list_entry

Rsrc TSRMLS_DC ){

ListNode current, next;

) Rsrc-> ptr; // rsrc-> ptr is a pointer type. here, the pointer type conversion will convert the resources pointed to by ptr to the linked list resources of ListNode?

While (current ){

Next = current-> next;

Free (current );

Current = next;

}

}

In this way, the memory of the entire linked list can be released.

While

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.