add(new \My\Foo()); * $collection->add(new \My\Foo()); * * foreach ($collection as $foo) { * if ($foo instanceof \My\FooInterface) { * // Do something with $foo * } * } * ``` * * It is preferable to subclass `AbstractCollection` to create your own typed * collections. For example: * * ``` php * namespace My; * /** * * @extends \Arrayy\Collection\AbstractCollection * *\/ * class FooCollection extends \Arrayy\Collection\AbstractCollection * { * public function getType() * { * return FooInterface::class; * } * } * ``` * * And then use it similarly to the earlier example: * * ``` php * namespace My; * * $fooCollection = new \My\FooCollection(); * $fooCollection->add(new \My\Foo()); * $fooCollection->add(new \My\Foo()); * * foreach ($fooCollection as $foo) { * if ($foo instanceof \My\FooInterface) { * // Do something with $foo * } * } * ``` * * INFO: this collection thingy is inspired by https://github.com/ramsey/collection/ * * @template TKey of array-key * @template T * @extends AbstractCollection */ class Collection extends AbstractCollection { /** * Constructs a collection object of the specified type, optionally with the * specified data. * * @param mixed $data *

* The initial items to store in the * collection. *

* @param string|null $iteratorClass optional

* You can overwrite the * ArrayyIterator, but mostly you * don't need this option. *

* @param bool $checkPropertiesInConstructor optional

* You need to extend the * "Arrayy"-class and you need to set * the * $checkPropertiesMismatchInConstructor * class property to true, otherwise * this option didn't not work * anyway. *

* @param TypeInterface|null $type * * @phpstan-param array|array|\Arrayy\Arrayy $data * @phpstan-param class-string<\Arrayy\ArrayyIterator> $iteratorClass */ public function __construct( $data = [], string $iteratorClass = null, bool $checkPropertiesInConstructor = null, TypeInterface $type = null ) { // fallback if ($iteratorClass === null) { $iteratorClass = ArrayyIterator::class; } if ($checkPropertiesInConstructor === null) { $checkPropertiesInConstructor = true; } if ($type !== null) { /* @phpstan-ignore-next-line - we use the "TypeInterface" only as base */ $this->properties = $type; } parent::__construct( $data, $iteratorClass, $checkPropertiesInConstructor ); } /** * @param string|TypeCheckArray|TypeCheckInterface[] $type * @param array $data * @param bool $checkPropertiesInConstructorAndType * * @return static * * @template TConstruct * @phpstan-param string|class-string|class-string|TypeInterface|TypeCheckArray|array $type * @phpstan-param array $data * @phpstan-return static */ public static function construct( $type, $data = [], bool $checkPropertiesInConstructorAndType = true ): self { $type = self::convertIntoTypeCheckArray($type); return new static( $data, ArrayyIterator::class, $checkPropertiesInConstructorAndType, $type ); } /** * Returns a new iterator, thus implementing the \Iterator interface. * * @return \Iterator *

An iterator for the values in the array.

* * @phpstan-return \Iterator * * @noinspection SenselessProxyMethodInspection */ public function getIterator(): \Iterator { return parent::getIterator(); } /** * The type (FQCN) associated with this collection. * * @return string|TypeCheckArray|TypeCheckInterface[] * * @phpstan-return string|class-string|class-string|TypeInterface|TypeCheckArray|TypeCheckArray|array|array */ public function getType() { return $this->properties; } /** * Get a base Collection instance from this Collection. * * @return self * * @phpstan-return self */ public function toBase(): self { return self::construct( $this->getType(), $this->getArray() ); } }