Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assigning property value through readonly array results in "Cannot modify readonly property" #15912

Open
SunMar opened this issue Sep 16, 2024 · 1 comment

Comments

@SunMar
Copy link

SunMar commented Sep 16, 2024

Description

The following code:

<?php
class A {
    public function __construct(
        public readonly array $a,
    ) {}
}

class B {
    public function __construct(
        public string $b,
    ) {
    }
}

$a = new A([ new B('foo') ]);
$a->a[0]->b = 'bar';

echo $a->a[0]->b;

Resulted in this output:

PHP Fatal error:  Uncaught Error: Cannot modify readonly property A::$a in /test.php:17

But I expected this output instead:

bar

If you try to change the property of an object that is inside a readonly array, based on syntax it thinks you're change the array itself and throws a Fatal, even though that property we're actually trying to change ($a->a[0]->b) is not readonly and can be changed. If the code to change the B::$b property is refactored like this the code works as expected:

$a = new A([ new B('foo') ]);
$b = $a->a[0];
$b->b = 'bar';

PHP Version

8.2.23, 8.3.11

Operating System

No response

@iluuu1994
Copy link
Member

This is related to #12244. For $foo['bar']->baz = 'baz';, both ['bar'] and ->baz are executed with BP_VAR_W. This used to be necessary, because -> would do autovivification itself. See PHP <8.0. https://3v4l.org/Q7RMT Since readonly disallows modification of arrays themselves, the fetch fails. Nowadays, we could switch to using BP_VAR_R for the ['bar'] fetch itself, but as #5250 has originally shown this breaks ext-simplexml. It also occurred to me that the current behavior is really useful for structs, which is why that PR was closed.

For now, I would consider this a wontfix.

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

No branches or pull requests

3 participants