So, i would like to implement something like this:
class Collection{
private $array;
public function add($object){
array_push($this->array, $object);
}
public function array(){
return $this->array;
}
}
class JustaClass{
public $myCollection;
public function __construct(){
$this->myCollection = new Collection();
}
}
$justAnObject = new JustaClass();
$justAnObject->myCollection->add(new SomeObject());
this works just fine, but i would like to work with it like i do in .Net, ie, when i want to refer to the collection Object, i would like to do it directly, like:
foreach($justAnObject->myCollection as $collectionItem)
and not like
foreach($justAnObject->myCollection->array() as $collectionItem)
Is there any way I can do this? maybe a magic method, or implementing an Iiterator-like interface?
thanks
Let your Collection
class implement the Iterator
or IteratorAggregate
interfaces. There's also an ArrayIterator
class, so it's really as easy as just returning an instance of that class:
class Collection implements IteratorAggregate {
private $array;
public function add($object){
array_push($this->array, $object);
}
/* required by IteratorAggregate */
public function getIterator() {
return new ArrayIterator($this->array);
}
}
You can then use your class in the following way:
$c = new Collection();
$c->add(1);
$c->add(2);
$c->add('we can even add strings');
foreach($c as $v) {
doSomething($v);
}
Actually, this is what SplObjectStorage
does, so no need to code anything:
The
SplObjectStorage
class provides a map from objects to data or, by ignoring data, an object Set. This dual purpose can be useful in many cases involving the need to uniquely identify objects.
It implements Countable
, Iterator
and ArrayAccess
, so you can foreach
it, access it with []
and use count
on it. Like the description says it's a Set, so it contains no duplicate elements.
If you want to allow for duplicate elements, you can simply use ArrayIterator
or ArrayObject
. You can find additional Data Structures similar to the various .NET collections in
IMO, there is no point in writing a custom class unless you also need to customize behavior of any of the options mentioned above.