php什么叫资源型,php:资源(resource)数据类型实例详解

什么是资源数据类型?

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

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

资源变量在PHP中的使用$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中对应的资源。#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,看出确实是对整型变量的赋值。

资源类型名称

为了区分资源类型,需要为我们定义的资源定义类型名称。#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函数: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函数: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中使用自定义扩展中的方法my_fwrite($fp, "aaTest");

var_dump($fp);

my_fclose($fp);

var_dump($fp);

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

释放资源

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

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

下一节,我们讲解两种特殊数据类型中的“空值(null)”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值