How to make objects in PHP perform foreach loop like arrays_PHP Tutorial

WBOY
Release: 2016-07-21 14:59:42
Original
850 people have browsed it

When I first came across the problem, I didn’t consider the Iterator mode. I tried a few general ideas and failed. . . . I went directly to look at the source code implementation of foreach, hoping to find out whether there are any special features when foreach handles objects, which can be used as a breakthrough.

After tracking for a long time, I found a strange switch in the core logic:

Copy the code 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?
Copy code 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;                                                      ;
}
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 Let’s talk about PHP’s built-in interface Iterator. PHP5 starts to support the interface and has a built-in Iterator interface. So 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 ZEND_ITER_PLAIN_OBJECT class, foreach will obtain the default attribute array of the object through HASH_OF, and then perform foreach on the array.

For ZEND_ITER_OBJECT class objects, foreach will be performed by calling the Iterator interface related functions implemented by the object. Iterator interface:

Copy code

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 )
}


So, for this written test question, you can give the following answer:
Copy the code 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 under my php 5.3.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/328120.htmlTechArticleWhen I first came across the question, I didn’t consider the Iterator mode. I tried a few general ideas and failed. . . . . I went directly to look at the source code implementation of foreach, expecting to find foreach...
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template