Skip to content

Allow Public Readonly Properties#28

Open
ashamrov wants to merge 1 commit intopaysera:masterfrom
ashamrov:readonly-public-property
Open

Allow Public Readonly Properties#28
ashamrov wants to merge 1 commit intopaysera:masterfrom
ashamrov:readonly-public-property

Conversation

@ashamrov
Copy link

Summary

  • Add exception for public readonly properties in DTOs and value objects
  • Add code example demonstrating the allowed pattern
  • Improve inline comment to clarify the alternative to public properties

Reasoning

Why allow public readonly properties?

PHP 8.1 introduced readonly properties which change the argument against public properties.
The concerns with public properties are:

  1. Uncontrolled mutation — External code can change internal state at any time
  2. No validation — Values can be set without any checks
  3. Tight coupling — Changing the internal representation breaks external code

public readonly addresses all of these:

Concern Regular public public readonly
Mutation Can be changed anywhere Immutable after construction
Validation No control Validated in constructor
Coupling Tight Acceptable for DTOs

Industry adoption

This pattern is widely adopted in modern PHP for:

  • Data Transfer Objects (DTOs)
  • Value Objects
  • API request/response models
  • Event payloads

Frameworks like Symfony and Laravel now use this pattern extensively. See Symfony 6.3: Mapping Request Data to Typed Objects.

Practical benefits

// Before: verbose boilerplate
class UserData {
    private string $id;
    private string $name;

    public function __construct(string $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }

    public function getId(): string { return $this->id; }
    public function getName(): string { return $this->name; }
}

// After: clean and concise
class UserData {
    public function __construct(
        public readonly string $id,
        public readonly string $name,
    ) {}
}

Both are equally safe, but the second is significantly more readable and maintainable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants