A readonly array is not deeply immutable

readonly prevents reassignment of the property and says nothing about what the property points at, which is obvious for objects and surprising for arrays.

final class Basket
{
    public function __construct(
        public readonly array $lines,
        public readonly Customer $customer,
    ) {}
}

$b->lines[] = $line;        // Error — arrays are values, so
                            // this is a modification of $lines

$b->customer->name = 'x';   // FINE. the reference is readonly;
                            // the object it points at is not.

The array case works better than expected because PHP arrays are value types, so appending is a write to the property and is refused. The object case is the real gap: a readonly property holding a mutable object gives an immutable reference to a mutable thing, which is a guarantee nobody wants. The only fix is that the contained objects are themselves immutable, all the way down, and nothing in the language checks that — it is a discipline with a keyword that looks like enforcement.