readonly plus a wither means a constructor call

clone copies the initialised state of a readonly property, so modifying the copy throws and every wither has to construct a new instance.

// does not work
public function withCurrency(string $c): self
{
    $copy = clone $this;
    $copy->currency = $c;   // Error: already initialised

    return $copy;
}

// what works, and gets verbose with six properties
public function withCurrency(string $c): self
{
    return new self($this->cents, $c);
}

The verbosity compounds: a value object with six properties lists all six in every wither, and adding a seventh means editing each one. A private helper taking an overrides array and spreading it into named arguments contains the repetition and introduces a coupling between parameter names and the array keys, which is acceptable because the array never leaves the class. The language fixes this properly in 8.3.