Reputation: 9829
I read the example of IteratorAggregate in PHP manual. I try to remove the IteratorAggregate interface but the outputs are similar with the implemented one.
<?php
class myData {
public $property1 = "Public property one";
public $property2 = "Public property two";
public $property3 = "Public property three";
public function __construct() {
$this->property4 = "last property";
}
}
$obj = new myData;
foreach($obj as $key => $value) {
var_dump($key, $value);
echo "\n";
}
Outputs:
string(9) "property1"
string(19) "Public property one"
string(9) "property2"
string(19) "Public property two"
string(9) "property3"
string(21) "Public property three"
string(9) "property4"
string(13) "last property"
I want to know that when we should implement IteratorAggregate interface? And why the ouputs are identical?
Upvotes: 1
Views: 795
Reputation: 70863
Now change your code to use PRIVATE or PROTECTED properties, and try again...
The current effect is that if you iterate over an object with public properties, the object is cast into an array, making all public properties the keys and values. And that's what you have.
With an interator interface you can iterate over values that are not available in public properties. They might as well be just produced the minute you are accessing them, i.e. fetched from a database.
Upvotes: 3
Reputation: 237845
The example in the manual page is not a great one, precisely because of what you describe here. The example class implements IteratorAggregate
and does this:
public function getIterator() {
return new ArrayIterator($this);
}
ArrayIterator
, when provided with an object, simply provides the public properties of the object. This can be done, as you demonstrate, simply by doing foreach
on the original object.
A more useful example would be if we wanted to reflect a different selection of values. For instance, let's say all those elements were private
and we didn't want to send $property3
:
class myData implements IteratorAggregate {
private $property1 = "Public property one";
private $property2 = "Public property two";
private $property3 = "Public property three";
public function __construct() {
$this->property4 = "last property";
}
public function getIterator() {
return new ArrayIterator(array(
'property1' => $this->property1,
'property2' => $this->property2,
'property4' => $this->property4
));
}
}
$obj = new myData;
foreach($obj as $key => $value) {
var_dump($key, $value);
echo "\n";
}
This would construct an iterator with the properties you wanted, not all of them.
You could construct any iterator in this way, even one entirely unrelated to the properties of the class. Often the best way to do this would be by implementing Iterator
, but sometimes if will be quicker to construct a new iterator object and point to that with getIterator
.
Upvotes: 5