foreach
PHP5提供了一种可以通过单元列表来遍历对象的方法,如果foreach语句,默认情况下,所有public属性都将被用于遍历。如果在类方法中进行遍历,还可以访问protected和private属性。从父类继承的属性也会被遍历。
<?php
class A{
public $var1="a";
public $var2="a2";
protected $var3="a3";
private $var4="a4";
public function showProperties(){
foreach ($this as $key=>$value) {
echo "$key=$value\n";
}
}
}
$a=new A();
$a->showProperties();
foreach ($a as $key=>$value) {
echo "$key=$value\n";
}
?>
Iterator
如果一个类实现了Iterator接口,则可以自行决定如何遍历以及每次遍历哪些值。当对一个实现了Iterator接口的对象进行foreach遍历的时候,会自动调用Iterator接口中定义的方法,rewind()->valid()->current()->key()->next()->valid()->current()->key()->next().....->valid()直到valid()返回false结束遍历。
遍历之前先调用rewind重置指针,valid验证是否循环结束,current获取当前指针处的值,key获取当前指针处的键,next移动指针,并返回移动后指针处的值。
<?php
class A implements Iterator{
public $var;
public $var1;
protected $var2;
private $var3;
private $var4;
private $arr=array();
public function __construct($arg,$arg1,$arg2,$arg3,$arg4){
$this->var=$arg;
$this->var1=$arg1;
$this->var2=$arg2;
$this->var3=$arg3;
$this->var4=$arg4;
$this->arr["var"]=$arg;
$this->arr["var1"]=$arg1;
$this->arr["var2"]=$arg2;
$this->arr["var3"]=$arg3;
}
public function rewind() {
echo "rewinding\n";
reset($this->arr);
}
public function current() {
$arr = current($this->arr);
echo "current: $arr\n";
return $arr;
}
public function key() {
$arr = key($this->arr);
echo "key: $arr\n";
return $arr;
}
public function next() {
$arr = next($this->arr);
echo "next: $arr\n";
return $arr;
}
public function valid() {
$arr = key($this->arr)!==null;
echo "valid: {$arr}\n";
return $arr;
}
}
$a = new A("a","a1","a2","a3","a4");
foreach ($a as $k => $v) {
print "$k: $v\n";
}
?>
IteratorAggregate
IteratorAggregate接口可以替代实现Iterator的方法。只需要实现IteratorAggregate接口的getIterator方法即可,此方法应返回一个实现了Iterator接口的类的实例。
<?php
class A implements IteratorAggregate{
public $var;
private $var1;
protected $var2;
private $arr=array();
function __construct($arg,$arg1,$arg2){
$var=$arg;
$var1=$arg1;
$va2r=$arg2;
$this->arr["var"]=$arg;
$this->arr["var1"]=$arg1;
$this->arr["var2"]=$arg2;
}
function getIterator(){
return new MyIterator($this->arr);
}
}
class MyIterator implements Iterator{
private $vars;
public function __construct($arr){
$this->vars=$arr;
}
public function rewind() {
echo "rewinding\n";
reset($this->vars);
}
public function current() {
$arr = current($this->vars);
echo "current: $arr\n";
return $arr;
}
public function key() {
$arr = key($this->vars);
echo "key: $arr\n";
return $arr;
}
public function next() {
$arr = next($this->vars);
echo "next: $arr\n";
return $arr;
}
public function valid() {
$arr = key($this->vars)!==null;
echo "valid: {$arr}\n";
return $arr;
}
}
$a=new A("a","a1","a2");
foreach ($a as $k => $v) {
print "$k: $v\n";
}
?>