在PHP中实现类似.Net的集合

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.