บทนำ
ตั้งแต่ PHP 5 เป็นต้นมา สามารถวนรอบ (Iterate) ผ่านรายการของสมาชิกที่มองเห็นได้ (Visible properties) ของออบเจ็กต์ได้ การวนรอบสามารถทำได้ด้วย:
- ลูป foreach
- Interface Iterator
- Interface IteratorAggregate
การใช้ foreach Loop
foreach จะวนรอบผ่านพร็อพเพอร์ตีที่มองเห็นได้ (public และ protected ในคลาสเดียวกัน, private ในคลาสเดียวกันเท่านั้น)
ตัวอย่าง
<?php
class myclass {
private $var;
protected $var1;
public $x, $y, $z;
public function __construct() {
$this->var = "private variable";
$this->var1 = TRUE;
$this->x = 100;
$this->y = 200;
$this->z = 300;
}
public function iterate() {
foreach ($this as $key => $value) {
print "$key => $value\n";
}
}
}
$obj = new myclass();
foreach($obj as $key => $value) {
print "$key => $value\n";
}
echo "\n";
$obj->iterate();
?>
ผลลัพธ์
x => 100 y => 200 z => 300 var => private variable var1 => 1 x => 100 y => 200 z => 300
หมายเหตุ: ภายนอกคลาส foreach มองเห็นเฉพาะ public properties เท่านั้น แต่ภายในเมธอดของคลาส (เช่น iterate()) จะมองเห็น protected และ private properties ของคลาสเดียวกันได้
การใช้ Iterator Interface
Interface Iterator กำหนด Abstract Methods 5 ตัวที่ต้อง Implement:
abstract public current ( void ) : mixed abstract public key ( void ) : scalar abstract public next ( void ) : void abstract public rewind ( void ) : void abstract public valid ( void ) : bool
| Method | หน้าที่ |
|---|---|
| current() | คืนค่า Element ปัจจุบัน |
| key() | คืนค่า Key ของ Element ปัจจุบัน |
| next() | เลื่อนไป Element ถัดไป |
| rewind() | 巻き戻し ไปยัง Element แรก |
| valid() | ตรวจสอบว่าตำแหน่งปัจจุบันถูกต้องหรือไม่ |
ตัวอย่างการ Implement Iterator
<?php
class myclass implements Iterator {
private $arr = array('a', 'b', 'c');
public function rewind() {
echo "rewinding\n";
reset($this->arr);
}
public function current() {
$var = current($this->arr);
echo "current: $var\n";
return $var;
}
public function key() {
$var = key($this->arr);
echo "key: $var\n";
return $var;
}
public function next() {
$var = next($this->arr);
echo "next: $var\n";
return $var;
}
public function valid() {
$key = key($this->arr);
$var = ($key !== NULL && $key !== FALSE);
echo "valid: $var\n";
return $var;
}
}
$obj = new myclass();
foreach ($obj as $k => $v) {
print "$k: $v\n";
}
?>
ผลลัพธ์
rewinding valid: 1 current: a key: 0 0: a next: b valid: 1 current: b key: 1 1: b next: c valid: 1 current: c key: 2 2: c next: valid:
IteratorAggregate Interface
ทางเลือกที่ง่ายกว่า คือ Implement IteratorAggregate ซึ่งต้องมีเพียงเมธอดเดียวคือ getIterator() ที่คืนค่า Iterator Instance
ตัวอย่าง
<?php
class myData implements IteratorAggregate {
private $data = ['a' => 1, 'b' => 2, 'c' => 3];
public function getIterator() {
return new ArrayIterator($this->data);
}
}
$obj = new myData();
foreach ($obj as $key => $value) {
echo "$key => $value\n";
}
?>