PHP Object Iteration

من موسوعة حسوب
< PHP
(بالتحويل من PHP/OOP/iterations)

يقدّم الإصدار الخامس من اللغة طريقة لتعريف العناصر ليكون بالإمكان المرور على قائمة من العناصر باستخدام العبارة foreach على سبيل المثال، وتستخدم جميع الخصائص المرئية بصورة افتراضية لعملية المرور على العناصر.

المثال 1: مثال بسيط على المرور على عناصر الكائن

<?php
class MyClass
{
    public $var1 = 'value 1';
    public $var2 = 'value 2';
    public $var3 = 'value 3';

    protected $protected = 'protected var';
    private   $private   = 'private var';

    function iterateVisible() {
       echo "MyClass::iterateVisible:\n";
       foreach ($this as $key => $value) {
           print "$key => $value\n";
       }
    }
}

$class = new MyClass();

foreach($class as $key => $value) {
    print "$key => $value\n";
}
echo "\n";


$class->iterateVisible();

?>

تعطي الشيفرة السابقة المخرجات التالية:

var1 => value 1
var2 => value 2
var3 => value 3

MyClass::iterateVisible:
var1 => value 1
var2 => value 2
var3 => value 3
protected => protected var
private => private var

يبين المثال السابق كيف أنّ عبارة foreach قد مرّت على جميع الخصائص المرئية التي يمكن الوصول إليها في الكائن.

يمكن استخدام واجهة iterator والتي تتيح للعنصر أن يملي الطريقة التي سيجري المرور على عناصره فيها والقيم التي ستكون متاحة في كل دورة.

المثال 2: استخدام واجهة Iterator

<?php
class MyIterator implements Iterator
{
    private $var = array();

    public function __construct($array)
    {
        if (is_array($array)) {
            $this->var = $array;
        }
    }

    public function rewind()
    {
        echo "rewinding\n";
        reset($this->var);
    }
  
    public function current()
    {
        $var = current($this->var);
        echo "current: $var\n";
        return $var;
    }
  
    public function key() 
    {
        $var = key($this->var);
        echo "key: $var\n";
        return $var;
    }
  
    public function next() 
    {
        $var = next($this->var);
        echo "next: $var\n";
        return $var;
    }
  
    public function valid()
    {
        $key = key($this->var);
        $var = ($key !== NULL && $key !== FALSE);
        echo "valid: $var\n";
        return $var;
    }

}

$values = array(1,2,3);
$it = new MyIterator($values);

foreach ($it as $a => $b) {
    print "$a: $b\n";
}
?>

تعطي الشيفرة السابقة المخرجات التالية:

rewinding
valid: 1
current: 1
key: 0
0: 1
next: 2
valid: 1
current: 2
key: 1
1: 2
next: 3
valid: 1
current: 3
key: 2
2: 3
next:
valid:

يمكن استخدام واجهة IteratorAggregate كبديل لجميع التوابع الخاصة بالواجهة Iterator. تتطلب الواجهة IteratorAggregate وجود تابع واحد فقط وهو IteratorAggregate::getIterator()‎ والذي يجب أن يعيد نسخة من الصنف الذي يستخدم الواجهة Iterator.

المثال 3: استخدام الواجهة IteratorAggregate

<?php
class MyCollection implements IteratorAggregate
{
    private $items = array();
    private $count = 0;

    // Required definition of interface IteratorAggregate
    public function getIterator() {
        return new MyIterator($this->items);
    }

    public function add($value) {
        $this->items[$this->count++] = $value;
    }
}

$coll = new MyCollection();
$coll->add('value 1');
$coll->add('value 2');
$coll->add('value 3');

foreach ($coll as $key => $val) {
    echo "key/value: [$key -> $val]\n\n";
}
?>

تعطي الشيفرة السابقة المخرجات التالية:

rewinding
current: value 1
valid: 1
current: value 1
key: 0
key/value: [0 -> value 1]

next: value 2
current: value 2
valid: 1
current: value 2
key: 1
key/value: [1 -> value 2]

next: value 3
current: value 3
valid: 1
current: value 3
key: 2
key/value: [2 -> value 3]

next:
current:
valid:
Note:

ملاحظة: يمكن لمستخدمي الإصدار 5.5 وما بعده منه اللغة الاطلاع على المولِّدات generators والتي تقدّم طريقة بديلة لتعريف المكرِّرات.

مصادر