Clone With — Modify Properties While Cloning
PHP 8.5 turns clone into a function that accepts property overrides. This is the "wither" pattern that readonly classes desperately needed — create a modified copy without boilerplate.
readonly class Color {
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255,
) {}
public function withAlpha(int $alpha): self {
return clone($this, ['alpha' => $alpha]);
}
public function darken(float $factor): self {
return clone($this, [
'red' => (int)($this->red * $factor),
'green' => (int)($this->green * $factor),
'blue' => (int)($this->blue * $factor),
]);
}
}
$blue = new Color(79, 91, 147);
$transparent = $blue->withAlpha(128);
$darkBlue = $blue->darken(0.5);
// $blue is unchanged — immutability preserved
echo $blue->alpha; // 255
echo $transparent->alpha; // 128
// Works with any class, not just readonly
$modified = clone($request, ['method' => 'POST', 'body' => $payload]);
Before PHP 8.5, creating a modified copy of a readonly object required manually passing every property to the constructor — even the ones that didn't change. clone() with overrides solves this elegantly.
Significance: Immutability
Immutable objects are only practical if creating modified copies is easy. Without
clone() with overrides, every readonly class needed hand-written wither methods that duplicated every property. Now the "with-er" pattern is a one-liner, making immutable design the path of least resistance.