• php资源类型变量


    php资源类型变量

    一、总结

    1、 php资源类型变量:用来打开文件、数据库连接、图形画布区域等的一种特殊变量,比如FILE *fp; 

    二、PHP: Resource 资源类型

    Resource 资源类型 ¶

    资源 resource 是一种特殊变量,保存了到外部资源的一个引用。资源是通过专门的函数来建立和使用的。所有这些函数及其相应资源类型见附录

    参见 get_resource_type()

    转换为资源 ¶

    由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄,因此将其它类型的值转换为资源没有意义。

    释放资源 ¶

    引用计数系统是 Zend 引擎的一部分,可以自动检测到一个资源不再被引用了(和 Java 一样)。这种情况下此资源使用的所有外部资源都会被垃圾回收系统释放。因此,很少需要手工释放内存。

    Note: 持久数据库连接比较特殊,它们不会被垃圾回收系统销毁。参见数据库永久连接一章。

    参考:

    PHP: Resource 资源类型 - Manual
    http://php.net/manual/zh/language.types.resource.php#language.types.resource

    三、php:资源(resource)数据类型实例详解

    什么是资源数据类型?

    资源数据类型是PHP4引进的。资源是一种特殊的变量类型,保存了到外部资源的一个引用:如打开文件、数据库连接、图形画布区域等。

    资源是通过专门的函数来建立和使用的。

    资源变量在PHP中的使用

    1
    2
    3
    4
    5
    $fp fopen("test.txt""rw"); 
       
    var_dump($fp); 
       
    fclose($fp);

    打印结果:resource(5) of type (stream)

    数字5:表示资源ID为5,具体含义后面介绍。

    stream:资源类型名称。

    资源ID

    内核中将注册的资源变量存储在一个HashTable中,并把资源所在HashTable中的key作为资源ID。

    所以,实际上PHP中的资源变量实际存储的是一个整型,通过这个ID找到HashTable中对应的资源。

    1
    2
    3
    #define Z_RESVAL(zval)          (zval).value.lval 
    #define Z_RESVAL_P(zval)        Z_RESVAL(*zval) 
    #define Z_RESVAL_PP(zval)       Z_RESVAL(**zval)

    上面的宏,是内核中ZE为资源变量赋值的API,看出确实是对整型变量的赋值。

    资源类型名称

    为了区分资源类型,需要为我们定义的资源定义类型名称。

    1
    2
    3
    4
    5
    6
    7
    #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)会在PHP作为SAPI(例如,Apache的mod_php5扩展)被加载到内存时,会执行所有扩展的ZEND_MINIT_FUNCTION。

    其中jinyong,是当前扩展的名字。例如此时扩展的名字就是jinyong

    这里为了方便理解,我们就把它认为是扩展在初始化时,会向内核中注册新的资源类型。

    创建资源变量

    资源类型已经注册成功,也为资源定义了区分的类型名称。现在可以使用这种资源的变量了。

    实现PHP中的fopen函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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返回资源变量 
    }

    这里,定义了PHP中名称为my_fopen的函数。my_fopen(string $file_name, string $mode)

    实现PHP中的fclose函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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; 
    }

    定义了PHP中名称为my_fclose的函数。my_fclose($resource)


    PHP中使用自定义扩展中的方法

    1
    2
    3
    4
    5
    6
    7
    my_fwrite($fp"aaTest"); 
       
    var_dump($fp); 
       
    my_fclose($fp); 
       
    var_dump($fp);

    可以正常,打开和关闭资源。

    释放资源

    由于 PHP4 Zend 引擎引进了资源计数系统,可以自动检测到一个资源不再被引用了(和 Java 一样)。这种情况下此资源使用的所有外部资源都会被垃圾回收系统释放。因此,很少需要用某些 free-result 函数来手工释放内存。

    注意: 持久数据库连接比较特殊,它们不会被垃圾回收系统破坏。

    参考:

    php:资源(resource)数据类型实例详解-php教程-PHP中文网
    http://www.php.cn/php-weizijiaocheng-360747.html

  • 相关阅读:
    CF601B Solution
    CF847F Solution
    CF877D Solution
    CF1472F Solution
    CF1472G Solution
    CF1355E Solution
    CF912D Solution
    CF1167F Solution
    shell脚本自动备份MySQL数据库
    centos7 crontab笔记
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/8996747.html
Copyright © 2020-2023  润新知