我要让指针遍历数组,得到如下结果该怎么做呢?

php的数组都有一个内部指针,指向数组的元素,初始化的时候是第一个,我要便利数组,让内部指针逐个移动

$arr = array ('a', 'b', 'c', 'd', 'e');foreach ($arr as $k => $v) {    $curr = current($arr);    echo "{$k} => {$v} -- {$curr}\n";
}

得到结果是

0 => a -- b1 => b -- b2 => c -- b3 => d -- b4 => e -- b

内部指针向后移动了一位就再也没动过了。
foreach对这个数组做了什么呢?为什么呢?

0 => a -- a1 => b -- b2 => c -- c3 => d -- d4 => e -- e


慕的地6264312
浏览 94回答 3
3回答

杨魅力

1. at the beginning of foreach: ZEND_FE_RESET which increase the refoucnt of $a2. then FE_FETCH, reset internal pointer of $a3. then current, current declared to accept a reference, but $a is not a ref and refcount > 1 , then -> separation

MYYA

foreach() 操作原始数组的一个拷贝,如果需要移动指针,使用 while 结构加上 each() 来实现。$arr = array ('a', 'b', 'c', 'd', 'e');reset($arr);while (list($k, $v) = each($arr)) {    # 当前指针已经被指向了下一位     $curr = current($arr);     echo "{$k} => {$v} -- {$curr}\n"; }

噜噜哒

php的所有变量实际上是用一个struct zval来表示的。/* 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; };而数组就是其中的"HashTable *ht",实际上就是一个哈希表(Hash Table),表中的所有元素同时又组成一个双向链表,它的定义为:/* 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;这里有一个 Bucket *pInternalPointer ,就是被reset/current/next等函数用来遍历数组保存位置状态的。Bucket的实现如下,可以看到这就是个赤裸裸的链表节点。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的实现,则位于 ./Zend/zend_compile.h ,在解释期被flex翻译成由 zend_do_foreach_begin zend_do_foreach_cont zend_do_foreach_end 这三个函数(以及相关代码)组合起来。
打开App,查看更多内容
随时随地看视频慕课网APP