php中的变量的值存储结构体如下:
typedef union _zvalue_value {
                                      long lval;                  /* long value */    
                                      doubledval;                /* double value */    
                                      struct {
                                                  char *val;
                                                   int len;
                                               } str;
                                       HashTable *ht;              /* hash table value */
                                         zend_object_value obj;
} zvalue_value;
这里使用联合体而不是用结构体是出于空间利用率的考虑,因为一个变量同时只能属于一种类型。利用strlen获取字符串长度时直接获取的是int len;
数组的存储是利用hashtable来实现的:PHP中的哈希表实现在Zend/zend_hash.c中:
typedef struct _hashtable {
    uint nTableSize;        // hash Bucket的大小,最小为8,以2x增长。    
uint nTableMask;        // nTableSize-1 , 索引取值的优化    
uint nNumOfElements;    // hash Bucket中当前存在的元素个数,count()函数会直接返回此值
ulongnNextFreeElement; // 下一个数字索引的位置
Bucket *pInternalPointer;   // 当前遍历的指针(foreach比for快的原因之一)
Bucket *pListHead;          // 存储数组头元素指针
   Bucket *pListTail;          // 存储数组尾元素指针
Bucket **arBuckets;         // 存储hash数组
   dtor_func_t pDestructor;    
zend_bool persistent;
   unsigned char nApplyCount; // 标记当前hash Bucket被递归访问的次数(防止多次递归)
zend_boolbApplyProtection;// 标记当前hash桶允许不允许多次访问,不允许时,最多只能递归3次
#if ZEND_DEBUG
   int inconsistent;
#endif
} HashTable;
看到利用count是直接获取数组的大小,不是经过循环计算的。