You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Protected properties are not scoped according to their prototype #19044
changed the title [-]Protected properties do not follow the same scoping rules than methods[/-][+]Protected properties are not scoped according to their prototype[/+]on Jul 5, 2025
@iluuu1994 Yeah, in the past there was not really a big point in repeating the property definition, so this was rather obscure and irrelevant. With property hooks you now can set protected abstract $prop { get; } on the parent class, so the child has to define it and then it breaks.
First, let me thank you maintainers for the work that you do on php.
I wanted to flag one knock-on issue here (also related to #19406, I think) which recently bit us when upgrading from 8.3. Namely, this change also impacts whether magic __set and __get methods are called when sibling classes assign to shared protected properties that are redeclared in the child. For example:
Simplified Example:
class SharedParent {
protected$id;
publicfunction__set($name, $value) {
echo"Running Setter $name$value\n";
$this->id = $value;
}
}
class ChildA extends SharedParent {
protected$id; // ChildA Redeclares the protected propertypublicfunctionset($txt) {
$this->id = $txt;
}
publicfunctionsetSibling($sibling, $txt) {
$sibling->id = $txt;
}
}
class ChildB extends SharedParent {
publicfunctionset($txt) {
$this->id = $txt;
}
publicfunctionsetSibling($sibling, $txt) {
$sibling->id = $txt;
}
}
$a = newChildA();
$b = newChildB();
$a->id = "testing";
$b->id = "123";
$a->set("testing");
$b->set("123");
$a->setSibling($b, "testing"); // does not run __set in 8.4.10$b->setSibling($a, "123"); // Runs __set in 8.4.11
Results in 8.4.11:
Running Setter id testing
Running Setter id 123
Running Setter id 123
Results in 8.4.12:
Running Setter id testing
Running Setter id 123
We ran into a situation where some of our model classes were altering properties of their siblings and expecting the __set methods to be called (marking the objects dirty). But this change made it so the setters weren't being called and, for us, objects not being saved to the DB (caught in testing, fortunately).
I'm writing this mostly for posterity—from our testing this behaviour was stable since 5.2.0 (released 2006). We agree it was a bug, but for us, it was a load-bearing bug. Hoping this comment helps someone else out.
And again, thanks for your hard work on improving php!
@jackweinbender Thanks for your feedback. Issues like this one are always tough. It's a clear bug, but I understand that even bug fixes have BC concerns, especially for long-standing bugs (Hyrum's law). We generally already postpone such fixes to the next minor release, though I suppose in this case we deemed the risk low, given before hooked properties were a thing there weren't many reasons to override properties.
Activity
bwoebi commentedon Jul 5, 2025
@iluuu1994 This was very surprising - I just checked the RFC and it says that they work the same than abstract methods:
So I assume this is a bug in the implementation?
[-]Protected properties do not follow the same scoping rules than methods[/-][+]Protected properties are not scoped according to their prototype[/+]iluuu1994 commentedon Jul 5, 2025
It looks like this is not unique to hooks or abstract properties. https://3v4l.org/OJWLS#v8.4.10
iluuu1994 commentedon Jul 5, 2025
Ah I see @bwoebi already got the solution. 🙂 Using
prop_info->prototypelooks like the right approach to me.bwoebi commentedon Jul 5, 2025
@iluuu1994 Yeah, in the past there was not really a big point in repeating the property definition, so this was rather obscure and irrelevant. With property hooks you now can set
protected abstract $prop { get; }on the parent class, so the child has to define it and then it breaks.Added that as a test case to the PR as well.
Fix phpGH-19044: Protected properties are not scoped according to the…
Fix GH-19044: Protected properties are not scoped according to their …
jackweinbender commentedon Mar 17, 2026
First, let me thank you maintainers for the work that you do on php.
I wanted to flag one knock-on issue here (also related to #19406, I think) which recently bit us when upgrading from 8.3. Namely, this change also impacts whether magic
__setand__getmethods are called when sibling classes assign to shared protected properties that are redeclared in the child. For example:Simplified Example:
Results in 8.4.11:
Results in 8.4.12:
We ran into a situation where some of our model classes were altering properties of their siblings and expecting the
__setmethods to be called (marking the objects dirty). But this change made it so the setters weren't being called and, for us, objects not being saved to the DB (caught in testing, fortunately).I'm writing this mostly for posterity—from our testing this behaviour was stable since 5.2.0 (released 2006). We agree it was a bug, but for us, it was a load-bearing bug. Hoping this comment helps someone else out.
And again, thanks for your hard work on improving php!
iluuu1994 commentedon Mar 17, 2026
@jackweinbender Thanks for your feedback. Issues like this one are always tough. It's a clear bug, but I understand that even bug fixes have BC concerns, especially for long-standing bugs (Hyrum's law). We generally already postpone such fixes to the next minor release, though I suppose in this case we deemed the risk low, given before hooked properties were a thing there weren't many reasons to override properties.