php中使对象可以像数组一样进行foreach循环的方法

  介绍

这篇文章将为大家详细讲解有关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   null

php中使对象可以像数组一样进行foreach循环的方法