shaku
can automatically generate type-safe Collection
and CollectionIterator
classes.
The recommended way to use this tool is a PHP Archive (PHAR):
$ wget https://phar.phpunit.de/shaku.phar
$ php shaku.phar --version
Furthermore, it is recommended to use Phive for installing and updating the tool dependencies of your project.
Alternatively, you may use Composer to download and install this tool as well as its dependencies. This is not recommended, though.
Consider you have a class named Value
(declared in src/Value.php
) and need a type-safe ValueCollection
for objects of this type:
namespace vendor;
final class Value
{
// ...
}
You can use this tool to automatically generate the code for the ValueCollection
and ValueCollectionIterator
class like so:
$ php shaku.phar --immutable vendor Value src
The above results in the generation of the code shown below:
<?php declare(strict_types=1);
namespace vendor;
final class ValueCollection implements \Countable, \IteratorAggregate
{
/**
* @var Value[]
*/
private $items = [];
public static function fromArray(array $items): self
{
$collection = new self;
foreach ($items as $item) {
$collection->add($item);
}
return $collection;
}
public static function fromList(Value ...$items): self
{
return self::fromArray($items);
}
private function __construct()
{
}
private function add(Value $item): void
{
$this->items[] = $item;
}
/**
* @return Value[]
*/
public function toArray(): array
{
return $this->items;
}
public function getIterator(): ValueCollectionIterator
{
return new ValueCollectionIterator($this);
}
public function count(): int
{
return \count($this->items);
}
public function isEmpty(): bool
{
return empty($this->items);
}
public function contains(Value $item): bool
{
foreach ($this->items as $_item) {
if ($_item === $item) {
return true;
}
}
return false;
}
}
<?php declare(strict_types=1);
namespace vendor;
final class ValueCollectionIterator implements \Countable, \Iterator
{
/**
* @var Value[]
*/
private $items;
/**
* @var int
*/
private $position;
public function __construct(ValueCollection $collection)
{
$this->items = $collection->toArray();
}
public function count(): int
{
return \iterator_count($this);
}
public function rewind(): void
{
$this->position = 0;
}
public function valid(): bool
{
return $this->position < \count($this->items);
}
public function key(): int
{
return $this->position;
}
public function current(): Value
{
return $this->items[$this->position];
}
public function next(): void
{
$this->position++;
}
}
$values = ValueCollection::fromArray([new Value, new Value]);
$values = ValueCollection::fromList(new Value, new Value);
$values = new ValueCollection;
$values->add(new Value);
$values->add(new Value);
This tool is named after "Shaku, the Collector", Copyright Blizzard Entertainment, Inc.