介绍
这篇文章将为大家详细讲解有关php中使对象可以像数组一样进行foreach循环的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
刚接触到题的时候,我也没有考虑到迭代器模式,试了几个一般想法,失败以后....就直接去翻看了foreach的源码实现,期望发现foreach处理对象的时候是否有什么特殊性,可以做为突破口。
跟踪了半天以后发现了核心逻辑中的一个奇怪的开关:
switch (zend_iterator_unwrap(数组,,,iter TSRMLS_CC)), { ,,,,,,,默认值: ,,,,,,,case ZEND_ITER_INVALID: ,,,,,,,,,,,,,..... ,,,,,,,,,,,,,,休息 ,,,,,,,case ZEND_ITER_PLAIN_OBJECT:, { ,,,,,,,,,,,,,,…… ,,,,,,,,,,,休息; ,,,,case ZEND_ITER_PLAIN_ARRAY: ,,,,,,,,,,..... ,,,,,,,,,,,休息; ,,,,,,,case ZEND_ITER_OBJECT: ,,,,,,,,,,…… ,,,,,,,,,,,休息; }
从这个结构,我们可以看的到,对象分为ZEND_ITER_OBJECT和ZEND_ITER_PLAIN_OBJECT,这是什么意思呢?
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; ,,,,,,,默认值: ,,,,,,,,,,,return ZEND_ITER_INVALID; ,,,} }
这就要讲到PHP的内置接口迭代器了,PHP5开始支持了接口,并且内置了迭代器接口,所以如果你定义了一个类,并实现了迭代器接口,那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT。
对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach。
而对于ZEND_ITER_OBJECT的类对象,则会通过调用对象实现的迭代器接口相关函数来进行foreach,迭代器接口:
Iterator extends Traversable {/*,方法,*/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  }
所以,对于这道笔试题,可以作出如下的答案:
class sample implements 迭代器 { ,,,private _items 美元;=,数组(1、2、3、4、5、6、7); ,,,public function __construct (), { ,,,,,,,,,,,,,,,,,,//空白 ,,,} ,,,public function 倒带(),{,重置($ this→_items);,} ,,,public function 电流(),{,return 电流($ this→_items);,} ,,,public function 关键(),{,return 关键($ this→_items);,} null null null null null null nullphp中使对象可以像数组一样进行foreach循环的方法