3 回答

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超6個(gè)贊
1. at the beginning of foreach: ZEND_FE_RESET which increase the refoucnt of $a
2. then FE_FETCH, reset internal pointer of $a
3. then current, current declared to accept a reference, but $a is not a ref and refcount > 1 , then -> separation

TA貢獻(xiàn)1868條經(jīng)驗(yàn) 獲得超4個(gè)贊
foreach()
操作原始數(shù)組的一個(gè)拷貝,如果需要移動(dòng)指針,使用 while
結(jié)構(gòu)加上 each()
來(lái)實(shí)現(xiàn)。
$arr = array ('a', 'b', 'c', 'd', 'e');reset($arr);while (list($k, $v) = each($arr)) { # 當(dāng)前指針已經(jīng)被指向了下一位 $curr = current($arr); echo "{$k} => {$v} -- {$curr}\n"; }

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超7個(gè)贊
php的所有變量實(shí)際上是用一個(gè)struct zval來(lái)表示的。
/* Zend/zend.h */typedef struct _zval_struct zval;typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; } zvalue_value;struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount; zend_uchar type; /* active type */ zend_uchar is_ref; };
而數(shù)組就是其中的"HashTable *ht",實(shí)際上就是一個(gè)哈希表(Hash Table),表中的所有元素同時(shí)又組成一個(gè)雙向鏈表,它的定義為:
/* Zend/zend_hash.h */typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; /* Used for element traversal */ 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;
這里有一個(gè) Bucket *pInternalPointer ,就是被reset/current/next等函數(shù)用來(lái)遍歷數(shù)組保存位置狀態(tài)的。Bucket的實(shí)現(xiàn)如下,可以看到這就是個(gè)赤裸裸的鏈表節(jié)點(diǎn)。
typedef struct bucket { ulong h; /* Used for numeric indexing */ uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; char arKey[1]; /* Must be last element */} Bucket;
而foreach的實(shí)現(xiàn),則位于 ./Zend/zend_compile.h ,在解釋期被flex翻譯成由 zend_do_foreach_begin zend_do_foreach_cont zend_do_foreach_end 這三個(gè)函數(shù)(以及相關(guān)代碼)組合起來(lái)。
- 3 回答
- 0 關(guān)注
- 165 瀏覽
添加回答
舉報(bào)