The PHP array has an internal pointer to the elements of the array, which is the first when initialized, I want to facilitate the array, let the internal pointer move one by one
$arr = Array (' A ', ' B ', ' C ', ' d ', ' E '), foreach ($arr as $k = = $v) { $curr = current ($arr); echo "{$k} = {$v}--{$curr}\n";}
Get the result is
0 = A--B1 = B--B2 = C--B3 + D--B4 + e--B
The internal pointer moves backwards, and one never moves.
What does foreach do with this array? Why is it?
I want the pointer to iterate through the array and get the following result.
0 = A--A1 = B--B2 = C--C3 + D--d4 + e--E
Reply content:
The PHP array has an internal pointer to the elements of the array, which is the first when initialized, I want to facilitate the array, let the internal pointer move one by one
$arr = Array (' A ', ' B ', ' C ', ' d ', ' E '), foreach ($arr as $k = = $v) { $curr = current ($arr); echo "{$k} = {$v}--{$curr}\n";}
Get the result is
0 = A--B1 = B--B2 = C--B3 + D--B4 + e--B
The internal pointer moves backwards, and one never moves.
What does foreach do with this array? Why is it?
I want the pointer to iterate through the array and get the following result.
0 = A--A1 = B--B2 = C--C3 + D--d4 + e--E
This question I answered on the bugs.php.net: https://bugs.php.net/bug.php?id=63752
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 are not a ref and RefCount > 1, then-separation
An array pointer operation function for PHP:
pos()
Http://cn2.php.net/manual/en/function ...
end()
Http://cn2.php.net/manual/en/function ...
prev()
Http://cn2.php.net/manual/en/function ...
next()
Http://cn2.php.net/manual/en/function ...
each()
Http://cn2.php.net/manual/en/function ...
reset()
Http://cn2.php.net/manual/en/function ...
current()
Http://cn2.php.net/manual/en/function ...
"Also Note that foreach operates in a copy of the specified array, not the array itself, therefore the array pointer Is isn't modified as with the All () construct and changes to the array element returned be not reflected in the original Array. "
Http://cn2.php.net/manual/en/control-...
foreach()
Manipulate a copy of the original array, if you need to move the pointer, using while
structure plus each()
to implement.
$arr = Array (' A ', ' B ', ' C ', ' d ', ' e '); reset ($arr); while (List ($k, $v) = each ($arr)) { # The current pointer has been pointed to the next $curr = cur rent ($arr); echo "{$k} = {$v}--{$curr}\n";}
See http://cn2.php.net/manual/en/function ... The example #2.
All the variables in PHP are actually represented by a 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;};
And the array is one of the "HashTable *ht", is actually a hash table (hash table), all the elements of the table is also composed of a doubly linked list, it is defined as:
/* 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;
Here is a Bucket *pinternalpointer, which is used by reset/current/next and other functions to iterate over the state of the array save position. The bucket is implemented as follows, and you can see that this is a naked list node.
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 is last element */} Bucket;
The implementation of foreach is located in./zend/zend_compile.h, which is translated by Flex during the interpretation period by Zend_do_foreach_begin Zend_do_foreach_cont Zend_do_foreach_end These three functions (and the associated code) are combined together. Because it looks more obscure, I do not post it (in fact, I do not understand), the details can refer to the snow migratory birds this: in-depth understanding of the PHP principle of the Foreach
Finally, a opcode of PHP code is attached.
number of ops:12compiled vars:!0 = $arr,! 1 = $xline # * OP r Eturn operands-----------------------------------------------------2 0 > Init_array ~0 1 Initialize array with 1 1 add_array_element ~0 2 Add 2 2 add_array_element ~0 3 Add 3 3 ASSIGN! 0, ~0 deposit $ARR3 4 > Fe_reset $! 0,->10 $ = fe_ RESET ($arr), failed to jump to # 5 > > Fe_fetch $6,->10 $ = fe_fetch ($), failure to skip to the # = Zend_op_data 7 ASSIGN! 1, $ $x = $34 8 ECHO !1 echo $x 9 > JMP->5 jump to # ten > SWITCH _free $ free > return 1 returns