Showing posts with label foreach. Show all posts
Showing posts with label foreach. Show all posts

Friday, June 5, 2009

Object iteration 2/2

about object iteration, in php5 it's possibile to use Iterators (similar to Java and C++).

Iterator is a PHP5 default interface that includes the public methods (to implement):
  • mixed current ( ) // returns the current element in the loop ($key)
  • scalar key ( ) // returns the current key in the loop ($val)
  • void next ( ) // called for obtain the next element
  • void rewind ( ) // rewind iterator to the 1st element (called at the beginning)
  • boolean valid ( ) // check if the current position is valid
class MyIt implements Iterator
{
public function current() {}
public function
key() {}
public function
next() {}
public function
rewind() {}
public function
valid() {}
}

Example (minimal):
We can create our class, keeping data in a private member and let these methods to access it.
We will use the php default function reset(), current(), next(), current() that easily allow to manage the element pointer in an array.

class A implements Iterator
{
private $ar = array();
public function
__construct($ar) { $this->ar = $ar; }
public function
current() {return current($this->ar);}
public function
key() {return key($this->ar);}
public function
next() { next($this->ar);}
public function
rewind() {reset($this->ar);}
public function valid() {return current($this->ar)!== false;}
}

$a = new A( array(1,2,3,4) );
foreach (
$a as $k=>$v)
{
print
" $k=>$v ";
}
//output: 0=>1 1=>2 2=>3 3=>4

Note: this is an example, we don't need to implement an iterator for a simple array. Pratically, we'll use an interator when we have different type of data (example: event calendar with a collection of events = customized objects).

IteratorAggregate
We've just built an implementation of an iterator for a class containing an array.
Now, let's suppose that we have a class B which manages his own array with other functionalities. If we want to use the previous iterator in the class B, we don't need to reimplement the interface Iterator.
It's enough to implement the class IteratorAggregate and his method getIterator() which returns a object which implements Iterator (the class A).

minimal example:

class B implements IteratorAggregate
{
private $bArray = array(6,7,8); //not a good/useful practice, but it's a minimal example !!
public function getIterator()
{
return new
A($this->bArray);
}
}


foreach (new
B() as $k=>$v)
{
print " $k=>$v ";

} //0=>6 1=>7 2=>8



Object iteration 1/2

the construct foreach in PHP5 supports also object, in addition to arrays.

foreach($object as $key=>$val)
{
//$key will be equal to the nth member name
//$val will be equal to the nth member value
}

Which members are visibile ? it depends on the "foreach" position !
  • inside the class ($this is the object): all the members are visibile
  • outside the class: only public members are visible
  • inside an inherited class: public and protected
Example:

class A
{
public $a;
public
$b;
private
$p;
public function
__construct($a, $b, $p){
$this->a = $a;$this->b = $b; $this->p = $p;
}
public function
f()
{

foreach(
$this as $k=>$v)

{print "$k => $v \n"; }
}
}

$a = new A(1,2,3);

foreach(
$a as $k=>$v)
{
print "$k => $v \n";
} //a => 1 b => 2

$a->f(); //a => 1 b => 2 p => 3
 

PHP and tips|PHP