Implement readonly properties #7089
Conversation
| @@ -154,6 +154,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); | |||
| %token <ident> T_PRIVATE "'private'" | |||
| %token <ident> T_PROTECTED "'protected'" | |||
| %token <ident> T_PUBLIC "'public'" | |||
| %token <ident> T_READONLY "'readonly'" | |||
iluuu1994
Jun 16, 2021
Member
Can this be added to semi_reserved?
Can this be added to semi_reserved?
|
Hi all, |
|
@matthieu88160 Constants are by definition readonly. Not sure how that would make sense. Also note that the mailing list is the primary tool for feedback when it comes to specification. |
My bad, I was thinking modification was allowed. |
|
@nikic Here are two more tests for useful use-cases of overriding a --TEST--
Visibility can change in readonly property
--FILE--
<?php
class A {
protected readonly int $prop;
public function __construct() {
$this->prop = 42;
}
}
class B extends A {
public readonly int $prop;
}
$a = new A();
try {
var_dump($a->prop);
} catch (\Error $error) {
echo $error->getMessage() . "\n";
}
$b = new B();
var_dump($b->prop);
?>
--EXPECT--
Cannot access protected property A::$prop
int(42)--TEST--
Can override readonly property with attributes
--FILE--
<?php
#[Attribute]
class FooAttribute {}
class A {
public readonly int $prop;
public function __construct() {
$this->prop = 42;
}
}
class B extends A {
#[FooAttribute]
public readonly int $prop;
}
var_dump((new ReflectionProperty(B::class, 'prop'))->getAttributes()[0]->newInstance());
?>
--EXPECT--
object(FooAttribute)#1 (0) {
} |
| $rp = new ReflectionProperty(Test::class, 'ro'); | ||
| var_dump($rp->isReadOnly()); | ||
| var_dump(($rp->getModifiers() & ReflectionProperty::IS_READONLY) != 0); | ||
|
|
mvorisek
Jun 24, 2021
Contributor
setValue by reflection should be tested here and allowed
setValue by reflection should be tested here and allowed
iluuu1994
Jun 24, 2021
Member
ReflectionProperty::setValue() can bypass the requirement that initialization occurs from the scope where the property has been declared. However, reflection cannot modify a readonly property that has already been initialized.
Allowing setValue on properties that have already been set breaks the assumption that the value can never change. This assumption is useful for not only the user but also the optimizer.
ReflectionProperty::setValue() can bypass the requirement that initialization occurs from the scope where the property has been declared. However, reflection cannot modify a readonly property that has already been initialized.
Allowing setValue on properties that have already been set breaks the assumption that the value can never change. This assumption is useful for not only the user but also the optimizer.
mvorisek
Jun 24, 2021
•
Contributor
But php is known for it's beaty that non-constants can be changed during runtime which makes debugging and hacking much easier.
But php is known for it's beaty that non-constants can be changed during runtime which makes debugging and hacking much easier.
kocsismate
Jun 24, 2021
Member
Nikita's standpoint has always been that we shouldn't allow such loopholes, and I also agree with him - Ilya pointed out the reasoning very clearly. PHP used to allow a lot of shady things in the past, but it's less and less true these days.
Nikita's standpoint has always been that we shouldn't allow such loopholes, and I also agree with him - Ilya pointed out the reasoning very clearly. PHP used to allow a lot of shady things in the past, but it's less and less true these days.
|
Method parameters can be readonly: |
|
Hey guys, I would like to add my few objections you might want to consider:
Of course there is option to merge both behaviors by adding modifier to readonly - so having Thank you for your attention and considering this opinions :) |
Please note that the feature is currently in voting, so any change should be warranted very much. Points 3 and 4 have already been discussed to death, I believe the RFC provides background information why the Implementing an Point 1 would render the feature broken, since any property value could be changed in private scope at any time, simply by unsetting it first. |
|
is_initialized() was recently discussed and declined (https://externals.io/message/114607). |
|
OK guys, thanks for your reply and sorry to bother you :) |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

RFC: https://wiki.php.net/rfc/readonly_properties_v2