博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php资源类型变量
阅读量:6081 次
发布时间:2019-06-20

本文共 3012 字,大约阅读时间需要 10 分钟。

php资源类型变量

一、总结

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

 

二、PHP: Resource 资源类型

Resource 资源类型

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

参见 

转换为资源

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

释放资源

引用计数系统是 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

 

转载地址:http://cykwa.baihongyu.com/

你可能感兴趣的文章
newinstance()和new有什么区别
查看>>
android下载封装类
查看>>
[node] 用 node-webkit 开发桌面应用
查看>>
Nginx访问控制和虚拟主机
查看>>
report widget not working for external users
查看>>
windows phone 摄像头得到图片是旋转90°
查看>>
Linux--sed使用
查看>>
没有显示器的情况下安装和使用树莓派
查看>>
Q85 最大矩形
查看>>
【android】使用handler更新UI
查看>>
mochiweb 源码阅读(十五)
查看>>
前端面试中的常见的算法问题
查看>>
计算机语言的基本理论
查看>>
nodejs流之行读取器例子
查看>>
批量文件重命名工具
查看>>
简单说一下UWP中的JumpList
查看>>
unity将object[]或者string对象转换成枚举enum
查看>>
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.19. 范围函数和操作符...
查看>>
以太坊系列之六: p2p模块--以太坊源码学习
查看>>
使用scikit-learn解决文本多分类问题(附python演练)
查看>>