Skip to content

[RFC] Allow Readonly Property Defaults#22588

Open
NickSdot wants to merge 4 commits into
php:masterfrom
NickSdot:readonly-property-defaults
Open

[RFC] Allow Readonly Property Defaults#22588
NickSdot wants to merge 4 commits into
php:masterfrom
NickSdot:readonly-property-defaults

Conversation

@NickSdot

@NickSdot NickSdot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Comment thread Zend/tests/readonly_classes/readonly_with_property_default.phpt Outdated
Comment thread Zend/tests/readonly_props/readonly_with_default_interface.phpt Outdated
// Unserialization still bypasses normal readonly assignment semantics.
var_dump(unserialize("O:11:\"TestDefault\":0:{}"));
var_dump(unserialize("O:11:\"TestDefault\":1:{s:4:\"prop\";i:2;}"));
var_dump(unserialize("O:11:\"TestDefault\":2:{s:4:\"prop\";i:2;s:4:\"prop\";i:3;}"));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is legal for properties to appear twice in serialization payload?! This probably should be deprecated and killed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same answer here, the test is also just copied from 12 lines above. Intention was to confirm that having a default value makes no difference. Do you want me to change something? How?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was an unrelated remark about serialization in general. Often one notices odd behavior about PHP while reviewing PRs.

No action needed from your side.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ref: #22599

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this once more after reading the RFC (and providing feedback on-list): I think this test is broken and effectively testing an implementation detail that is not usually observable.

The duplicate property is actually written twice (and readonly ignored) when no __unserialize() hook exists, but when an __unserialize() hook exists, only the latter version for the same key will be seen by the hook.

And similarly for a readonly property with a default value (i.e. the new feature), without __unserialize() the default will be overwritten, but __unserialize() will not be able to set it, because it is beholden to the regular readonly rules.

When you add:

    public function __unserialize(array $data): void
    {
        foreach ($data as $key => $val) {
                $this->{$key} = $val;
        }
    }

then you'll get:

Error: Cannot modify readonly property TestDefault::$prop in

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants