对于php来说,foreach是一种非常方便易用的语法,几乎是每一个PHPer最常遇到的请求之一。那么是否可以通过foreach来遍历对象呢?答案是肯定的,但是有一个条件,就是对象的遍历只能获取到它的公共属性。//普通遍历类A{public$a1='1';公共$a2='2';公共$a3='3';私人$a4='4';保护$a5='5';公共$a6='6';公共功能测试(){回声'测试';}}$a=newA();foreach($aas$k=>$v){echo$k,'===',$v,PHP_EOL;}//a1===1//a2===2//a3===3//a6===6无论是方法还是protected或private变量,都无法遍历。只能遍历公共属性。其实我们之前讲设计模式的时候提到的迭代器模式就是专门用于对象遍历的,而PHP已经为我们准备好了相关的接口,我们只需要实现这个接口就可以完成迭代器模式的创建。具体内容可以参考之前的设计模式系列文章:PHP设计模式之Iteratorpattern//ImplementiteratorinterfaceclassBimplementsIterator{private$var=[];公共函数__construct($array){if(is_array($array)){$this->var=$array;}}publicfunctionrewind(){echo"倒带\n";重置($this->var);}publicfunctioncurrent(){$var=current($this->var);echo"current:$var\n";返回$var;}publicfunctionkey(){$var=key($this->var);echo"key:$var\n";返回$var;}publicfunctionnext(){$var=next($this->var);echo"下一个:$var\n";返回$var;}publicfunctionvalid(){$var=$this->current()!==false;echo"有效:{$var}\n";返回$var;}}$b=新B([1,2,3,4]);foreach($bas$k=>$v){echo$k,'===',$v,PHP_EOL;}//倒带//当前:1//有效:1//当前:1//键:0//0===1//next:2//current:2//valid:1//current:2//key:1//1===2//next:3//current:3//有效:1//current:3//key:2//2===3//next:4//current:4//valid:1//current:4//key:3//3===4//next://current://valid:如果今天的文章只是讲之前提到的迭代器模式,那就太无聊了,所以我们要学习一个更有趣的应用,让对象可以像数组一样进行操作。这其实是PHP已经为我们准备好的一个接口:ArrayAccess。//让类可以像数组一样操作classCimplementsArrayAccess,IteratorAggregate{private$container=[];publicfunction__construct(){$this->container=["one"=>1,"two"=>2,"three"=>3,];}publicfunctionoffsetSet($offset,$value){if(is_null($offset)){$this->container[]=$value;}else{$this->container[$offset]=$value;}}publicfunctionoffsetExists($offset){returnisset($this->container[$offset]);}publicfunctionoffsetUnset($offset){unset($this->container[$offset]);}publicfunctionoffsetGet($offset){returnisset($this->container[$offset])?$this->容器[$offset]:空;}publicfunctiongetIterator(){returnnewB($this->container);}}$c=newC();var_dump($c);$c['四']=4;var_dump($c);$c[]=5;$c[]=6;var_dump($c);foreach($cas$k=>$v){echo$k,'===',$v,PHP_EOL;}//倒带//current:1//valid:1//current:1//key:one//one===1//next:2//current:2//valid:1//current:2//key:two//two===2//next:3//当前:3//有效:1//当前:3//键:三//三===3//下一个:4//当前:4//有效:1//当前:4//键:四//four===4//next:5//current:5//valid:1//current:5//key:0//0===5//next:6//current:6//valid:1//current:6//key:1//1===6//next://current://valid:这个接口需要我们实现四个方法:offsetSet($offset,$value),根据偏移量设置值offsetExists($offset),根据偏移量判断是否有内容offsetUnset($offset),根据偏移量删除内容offsetGet($offset),根据模糊获取内容数量。这里的偏移就是我们常说的下标,通过实现这四个方法,我们就可以像操作数组一样操作对象了。当然,在日常开发中,我们可能不会经常使用这些对象遍历能力,包括迭代器。通常我们会直接将对象转化为数组(array)obj,以备下一步使用。但是在java中,尤其是JavaBean中,类内部往往会有一个List
