深入PHP-变量类型底层实现及strlen和count函数探讨

最近在看《深入理解PHP内核》,网址:点击打开链接

看到了比较基础的变量的底层实现,明白了php是如何在强类型语言-C语言的基础上成为了弱类型语言

首先来看一下php变量的底层结构:看不懂C结构的请移步C语言基础教程~学好C对深入理解php还是很有帮助的

typedef struct _zval_struct zval;
struct _zval_struct {
	zvalue_value value; // 变量的值,$a='abc';$a=123;$a=array(123,456,789);这些变量值都是放在这个结构体中的
	zend_uint refcount__gc; // 引用计数,用于垃圾回收
	zend_uchar type; // 变量类型,IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT、IS_RESOURCE
	zend_uchar is_ref__gc; // 是否为引用
};
在看一下zvalue_value结构体是如何存储变量的值的

typedef union _zvalue_value {
	long lval; // 整形值
	double dval; // 浮点型值
	struct { // 字符串值
		char *val;
		int len; // 看到了吗?字符串在赋值后就有长度这个值,所以放心大胆的用strlen吧
	} str;
	HashTable *ht; // 数组值
	zend_object_value obj; // 对象值
} zvalue_value;
这是一个union共同体,顾名思义,其中的各种类型只用一份内存空间,因为一个变量一旦赋值,那么它只能对应一种类型,那么他的类型也就确定的,比如是整形,那就存储在lval中,如果是字符串,那就存储在str结构体中

下面在看下数组的实现方式 HashTable

typedef struct _hashtable {
	uint nTableSize;
	uint nTableMask;
	uint nNumOfElements; // HashTable即数组中元素的数量
	ulong nNextFreeElement;
	Bucket *pInternalPointer; // foreach比for快的原因
	Bucket *pListHead;
	Bucket *pListTail;
	Bucket **arBuckets;
	dtor_func_t pDestructor;
	zend_bool persistent;
	unsigned char nApplyCount;
	zend_bool bApplyProtection;
	#if ZEND_DEBUG
	int inconsistent;
	#endif
} HashTable;

typedef struct _Bucket {
        char *key;
        void *value;
        struct _Bucket *next;
} Bucket;

这里主要说一下nNumOfElements这个参数,即数组中元素的数量,对应的是count()方法别名sizeof()

下面探讨下 for($i=0; $i<count($arr); $i++) 和 $count = count($arr); for($i=0; $i<$count; $i++) 效率问题,后者效率明显要高于前者,原因如下:

虽然count($arr)不会重新计算数组长度,而是直接取nNumOfElements,但是调用如下:zval.value.ht.nNumOfElements;而$count变量的调用只有一层,所以还是局部变量的效率更高一些

这是我从其中发现的一些知识点,如有不对的地方,还请大家指正,共同学习!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值