What is a resource data type?
The resource data type is introduced in PHP4. Resource is a special variable type that holds a reference to an external resource: such as an open file, database connection, graphics canvas area, etc.
Resources are created and used through specialized functions.
Use of resource variables in PHP
$fp = fopen("test.txt", "rw"); var_dump($fp); fclose($fp);
Print results: resource(5) of type (stream)
Number 5: Indicates that the resource ID is 5, the specific meaning follows introduce.
stream: resource type name.
Resource ID
The kernel stores the registered resource variables in a HashTable, and uses the key in the HashTable where the resource is located as the resource ID.
So, in fact, the resource variable in PHP actually stores an integer, and the corresponding resource in the HashTable is found through this ID.
#define Z_RESVAL(zval) (zval).value.lval #define Z_RESVAL_P(zval) Z_RESVAL(*zval) #define Z_RESVAL_PP(zval) Z_RESVAL(**zval)
The above macro is the API used by ZE in the kernel to assign values to resource variables. It can be seen that it is indeed an assignment to an integer variable.
Resource type name
In order to distinguish resource types, we need to define type names for the resources we define.
#define MY_RES_NAME "my_resource" //资源类型名称,PHP通过var_dump打印资源变量时会看到这个名称 static int my_resource_descriptor; ZEND_MINIT_FUNCTION(jinyong) { my_resource_descriptor = zend_register_list_destructors_ex(NULL, NULL, MY_RES_NAME, module_number);//向内核中注册新的资源类型 }
ZEND_MINIT_FUNCTION(jinyong) will execute ZEND_MINIT_FUNCTION of all extensions when PHP is loaded into memory as a SAPI (for example, Apache's mod_php5 extension).
Among them, jinyong is the name of the current extension. For example, the name of the extension at this time is jinyong
For the convenience of understanding, we think of it as the extension registering a new resource type with the kernel during initialization.
Creating resource variables
The resource type has been successfully registered, and a differentiated type name has been defined for the resource. Variables for this resource can now be used.
Implementing the fopen function in PHP:
PHP_FUNCTION(my_fopen) { zval *res; char *filename, *mode; int filename_strlen, mode_strlen; FILE *fp; if(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "s|s", &filename, &filename_strlen, &mode, &mode_strlen) == FAILURE){ RETURN_FALSE; } //此处省略了对参数的有效性验证 fp = fopen(filename, mode); ZEND_REGISTER_RESOURCE(res, fp, my_resource_descriptor);//向全局变量&EG(regular_list)中注册资源变量,并将对应HashTable的ID赋值给res RETURN_RESOURCE(res);//向PHP返回资源变量 }
Here, the function named my_fopen in PHP is defined. my_fopen(string $file_name, string $mode)
Implements the fclose function in PHP:
PHP_FUNCTION(my_fclose) { zval *res; FILE *fp; if(zend_parse_parameters(ZEND_NUM_ARGS TSRMS_CC, "r", &res) == FAILURE){ RETURN_FALSE; } if(Z_TYPE_P(res) == IS_RESOURCE){//判断变量类型是否是资源类型 zend_hash_index_del(&EG(regular_list), Z_RESVAL_P(res));//EG就类似于PHP中的$_GLOBALS。在全局资源变量regular_list中删除对应ID的资源 }else{ php_error_docref(NULL TSRMLS_CC, E_WARNING, "参数必须是资源类型变量"); RETURN_FALSE; } RETURN_TRUE; }
defines the function named my_fclose in PHP. my_fclose($resource)
Using the method in the custom extension in PHP
my_fwrite($fp, "aaTest"); var_dump($fp); my_fclose($fp); var_dump($fp);
can open and close resources normally.
Release resources
Since the PHP4 Zend engine has introduced a resource counting system, it can automatically detect that a resource is no longer referenced (same as Java). In this case, all external resources used by this resource will be released by the garbage collection system. Therefore, it is rarely necessary to manually free memory using some free-result function.
Note: Persistent database connections are special, they will not be destroyed by the garbage collection system.
In the next section, we will explain the "null value (null)" among the two special data types.
The above is the detailed content of PHP: Detailed explanation of resource data type examples. For more information, please follow other related articles on the PHP Chinese website!