The library provides a helper methods for immutable objects.
composer require jasny/immutable
The Jasny\Immutable\NoDynamicProperties
defines the __set
method, which will throw a LogicException
when
attempting to set a non-existing property.
class ImmutableFoo
{
use Jasny\Immutable\NoDynamicProperties;
}
Immutable objects may have with...
methods, that create an altered version of the object, while the immutable object
itself remains unchanged. An example are classes work as described in PSR-7.
The with...
methods in these objects typically follow the same method.
class ImmutableFoo
{
public function withSomething(string $newValue)
{
if ($this->something === $newValue) {
return $this;
}
$clone = clone $this;
$clone->something = $newValue;
return $clone;
}
}
The Jasny\Immutable\With
trait implements a protected withProperty()
and withoutProperty()
method for setting and
unsetting properties on a clone of the object.
class ImmutableFoo
{
use Jasny\Immutable\With;
protected $something;
public function withSomething(string $value): self
{
return $this->withProperty('something', $value);
}
public function withoutSomething(): self
{
return $this->withoutProperty('something');
}
}
The trait contains the withPropertyKey()
and withoutPropertyKey()
methods for setting and unsetting an item of an
associative array.
class ImmutableFoo
{
use Jasny\Immutable\With;
protected array $colors = [];
public function withColor(string $color, int $level): self
{
return $this->withPropertyKey('colors', $color, $level);
}
public function withoutColor(string $color): self
{
return $this->withoutPropertyKey('colors', $color);
}
}
The withPropertyItem()
and withoutPropertyItem()
methods work on a sequential array to add and remove an item.
class ImmutableFoo
{
use Jasny\Immutable\With;
protected array $services = [];
public function withAddedService($service): self
{
return $this->withPropertyItem('services', $service, true /* unique */);
}
public function withoutService($service): self
{
return $this->withoutPropertyItem('services', $service);
}
}
If the third argument of withPropertyItem()
is set to true
, the item isn't added if it's already in the array.
If the item is in the array multiple times, withoutPropertyItem()
will remove them all. Strict comparison is used to
find items.