On 1 July 2026 12:25:53 BST, Nick Sdot <[email protected]> wrote:
>You cannot do the below with a hook. Having the primary constructor body
>solves it:
>
>```
>
>final readonly class Foo(Collection|array $value) implementsBar {
> $this->items = $value instanceof Collection ? $value : new
> Collection($value);
>}=> {
> // class body private Collection $items
>
>}
>
>```
OK, I think I get it. But a normal constructor also works just fine. You don't
have to "remove readonly and check the whole class", you just add exactly the
code you've added above, but move the constructor parameters from next to the
class name to next to the word "__construct":
```
final readonly class Foo implements Bar {
public function __construct(Collection|array $value) {
$this->items = $value instanceof Collection ? $value : new
Collection($value);
}
private Collection $items
}
```
If we're talking about refactoring, the previous version presumably looked like
this:
```
final readonly class Foo(private Collection $items) implements Bar {
// ...
}
```
So whether the refactoring is "add a constructor and a property declaration" or
"add a primary constructor body and a property declaration" doesn't make much
difference. The readonly keyword, and the rest of the class, stay exactly the
same.
The appeal of the primary constructor syntax to me is that it's concise and
does everything in one go. As soon as you add an explicit body and a separate
property declaration, you've lost the conciseness, regardless of where you put
that body; so you might as well just use the existing syntax rather than
inventing a new one.
Rowan Tommins
[IMSoP]