In php, how can we make objects perform a foreach loop like an array. I didn't take into account the Iterator mode when I first got into touch with the question. I tried some general ideas, and after the failure .... I directly looked at the source code implementation of foreach and expected to find that when foreac first came into contact with the question, I did not consider the Iterator mode. I tried some general ideas and failed to do so .... I directly looked at the source code implementation of foreach, hoping to find out whether there is any special feature when foreach processes objects. it can be used as a breakthrough.
After tracking for half a day, we found a strange switch in the core logic:
The code is as follows:
Switch (zend_iterator_unwrap (array, & iter TSRMLS_CC )){
Default:
Case ZEND_ITER_INVALID:
.....
Break
Case ZEND_ITER_PLAIN_OBJECT :{
......
Break;
Case ZEND_ITER_PLAIN_ARRAY:
.....
Break;
Case ZEND_ITER_OBJECT:
......
Break;
}
From this structure, we can see that the objects are divided into ZEND_ITER_OBJECT and ZEND_ITER_PLAIN_OBJECT. what does this mean?
The code is as follows:
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap (
Zval * array_ptr, zend_object_iterator ** iter TSRMLS_DC)
{
Switch (Z_TYPE_P (array_ptr )){
Case IS_OBJECT:
If (Z_OBJ_HT_P (array_ptr) ==& iterator_object_handlers ){
* Iter = (zend_object_iterator *) zend_object_store_get_object (array_ptr TSRMLS_CC );
Return ZEND_ITER_OBJECT;
}
If (HASH_OF (array_ptr )){
Return ZEND_ITER_PLAIN_OBJECT;
}
Return ZEND_ITER_INVALID;
Case IS_ARRAY:
If (HASH_OF (array_ptr )){
Return ZEND_ITER_PLAIN_ARRAY;
}
Return ZEND_ITER_INVALID;
Default:
Return ZEND_ITER_INVALID;
}
}
This is about PHP's built-in interface Iterator. PHP5 starts to support interfaces and has built-in Iterator interfaces. Therefore, if you define a class and implement the Iterator interface, then, your class object is ZEND_ITER_OBJECT. Otherwise, it is ZEND_ITER_PLAIN_OBJECT.
For the class ZEND_ITER_PLAIN_OBJECT, foreach obtains the default attribute array of the object through HASH_OF, and then performs foreach on the array.
For the class object of ZEND_ITER_OBJECT, The foreach and Iterator interfaces are performed by calling the iterator interface related functions implemented by the object:
The code is as follows:
Iterator extends Traversable {
/* Method */
Abstract public mixed current (void)
Abstract public scalar key (void)
Abstract public void next (void)
Abstract public void rewind (void)
Abstract public boolean valid (void)
}
Therefore, you can give the following answers to this question:
The code is as follows:
Class sample implements Iterator
{
Private $ _ items = array (1, 2, 3, 4, 5, 6, 7 );
Public function _ construct (){
; // Void
}
Public function rewind () {reset ($ this-> _ items );}
Public function current () {return current ($ this-> _ items );}
Public function key () {return key ($ this-> _ items );}
Public function next () {return next ($ this-> _ items );}
Public function valid () {return ($ this-> current ()! = False );}
}
$ Sa = new sample ();
Foreach ($ sa as $ key => $ val ){
Print $ key. "=>". $ val;
}
The above code runs normally in my php 5.3.
Bytes .... I directly looked at the foreach source code implementation and expected to find foreac...