您的位置:首页 > 编程语言 > PHP开发

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

2017-01-05 11:53 591 查看
最近在看《深入理解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变量的调用只有一层,所以还是局部变量的效率更高一些

这是我从其中发现的一些知识点,如有不对的地方,还请大家指正,共同学习!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息