PHP Resource types

Source: Internet
Author: User

In PHP, we often use a resource type variable. For example: MySQL connection, file handle, and so on.

These variables cannot be represented by scalar, so how do you connect the resource variables in PHP to the resources in the C language in the Zend kernel?


One, the use of resource variables in PHP

[PHP]View PlainCopy
    1. $fp = fopen ("test.txt", "RW");
    2. Var_dump ($fp);
    3. Fclose ($fp);


Printed Result: Resource (5) of type (stream)

The number 5: Indicates a resource ID of 5, which is described later.

Stream: Resource type name.


Second, the resource ID

The kernel stores the registered resource variables in a hashtable and takes the key in the hashtable of the resource as the resource ID.

So, in fact, the resource variables in PHP actually store an integer type, which is the ID to find the corresponding resource in Hashtable.

[CPP]View PlainCopy
    1. #define Z_RESVAL (Zval) (zval). Value.lval
    2. #define Z_RESVAL_P (Zval) z_resval (*zval)
    3. #define Z_RESVAL_PP (Zval) z_resval (**zval)

The above macro, which is the API for assigning a value to a resource variable in the kernel, shows that the ze is indeed assigned to an integer variable.


Iii. Resource type name

To differentiate between resource types, you need to define the type name for the resource that we define.

[CPP]View PlainCopy
    1. #define MY_RES_NAME "My_resource"//resource type name, PHP will see this name when printing resource variables through Var_dump
    2. static int my_resource_descriptor;
    3. Zend_minit_function (Jinyong)
    4. {
    5. My_resource_descriptor = ZEND_REGISTER_LIST_DESTRUCTORS_EX (null, NULL, My_res_name, module_number); //Register new resource types with the kernel
    6. }


Zend_minit_function (Jinyong) will perform all the extended zend_minit_function when PHP is loaded into memory as a SAPI (for example, an Apache MOD_PHP5 extension).

Where Jinyong, is the name of the current extension. For example, the name of the extension is Jinyong

Here, for the sake of understanding, we think of it as an extension that, when initialized, registers a new resource type with the kernel.


Iv. Creating resource variables

The resource type has been registered successfully, and the distinguished type name is defined for the resource. You can now use the variables for this resource.

Implement the Fopen function in PHP:

[CPP]View PlainCopy
  1. Php_function (My_fopen)
  2. {
  3. Zval *res;
  4. Char *filename, *mode;
  5. int Filename_strlen, Mode_strlen;
  6. FILE *FP;
  7. if (zend_parse_parameters (Zend_num_args tsrmls_cc, "S|s", &filename, &filename_strlen, &mode, &mode_strlen) = = FAILURE) {
  8. Return_false;
  9. }
  10. //The validation of parameters is omitted here
  11. fp = fopen (filename, mode);
  12. Zend_register_resource (res, FP, my_resource_descriptor); register the resource variable in the global variable &eg (regular_list) and assign the ID of the corresponding hashtable to res
  13. Return_resource (RES); //Return resource variable to PHP
  14. }

Here, a function named My_fopen is defined in PHP. My_fopen (String $file _name, String $mode)


Implement the Fclose function in PHP:

[CPP]View PlainCopy
  1. Php_function (My_fclose)
  2. {
  3. Zval *res;
  4. FILE *FP;
  5. if (zend_parse_parameters (Zend_num_args tsrms_cc, "R", &res) = = FAILURE) {
  6. Return_false;
  7. }
  8. if (z_type_p (res) = = Is_resource) {//Determine if the variable type is a resource type
  9. Zend_hash_index_del (&eg (regular_list), z_resval_p (res)); //eg is similar to the $_globals in PHP. Delete the resource of the corresponding ID in the global resource variable regular_list
  10. }else{
  11. Php_error_docref (NULL tsrmls_cc, e_warning, "parameter must be a resource type variable");
  12. Return_false;
  13. }
  14. Return_true;
  15. }

Defines a function in PHP with the name My_fclose. My_fclose ($resource)

V. Compile, install extensions, restart PHP-FPM or MOD_PHP5, etc.


Vi. methods used in custom extensions in PHP

[PHP]View PlainCopy
    1. My_fwrite ($fp, "aatest");
    2. Var_dump ($fp);
    3. My_fclose ($fp);
    4. Var_dump ($fp);

You can open and close the resource normally.


Seven, we often use the database connection resources in PHP, file handle resources, but they usually do not need us to manually release, there is no memory leak problem, how is this implemented?

[CPP]View PlainCopy
    1. My_resource_descriptor = ZEND_REGISTER_LIST_DESTRUCTORS_EX (null, NULL, My_res_name, module_number); //Register new resource types with the kernel

Back to the beginning of the registered resource type, see the first parameter of ZEND_REGISTER_LIST_DESTRUCTORS_EX, which is a pointer to the destructor.

Then, if you need to implement automatic deallocation, you only need to define destructors and pass function pointers.


Look at one more question:

[PHP]View PlainCopy
    1. $fp = fopen ("test.txt", "RW");
    2. Var_dump ($fp);
    3. Fclose ($FP); Do not use fclose to free resources here
    4. unset ($fp); //Use unset to release
    5. Unset no problem, the $FP variable is released normally. But $fp corresponds to a real open file resource handle resource will never be released until MOD_PHP5 or PHP-FPM restarts
    6. As you can see, it is necessary to define the destructor when registering the resource type.


To define a destructor:

[CPP]View PlainCopy
    1. static void Php_myres_dtor (Zend_rsrc_list_entry *rsrc tsrmls_dc) {//The destructor is called when a parameter of the current resource variable is accepted
    2. FILE *FP = (file*) rsrc->ptr;
    3. Fclose (FP);
    4. }
    5. Zend_minit_function (Jinyong)
    6. {
    7. My_resource_descriptor = ZEND_REGISTER_LIST_DESTRUCTORS_EX (Php_myres_dtor, NULL, My_res_name, Module_number);
    8. }
[CPP]View PlainCopy
      1. In PHP, the so-called resource variables, in fact, by storing integer values, in the kernel global resource variable list eg (regular_list) to find the corresponding pointer, and the corresponding operation.
      2. PHP resource variables, the reason is not to worry about similar MySQL connection not release problems, but also because the extension of the definition of the destructor method, help to automatically release.

PHP Resource types

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.