I originally wrote a long af reply ... but now I agree that this is a bug as
well after writing it out ...
I’ll be referring to the following code:
class A {
protected int $v = 1;
}
class B extends A {}
class C extends A {
protected int $v = 2;
}
class D extends A {
protected int $v = 3 { get => $this->v * 2 }
}
---
Reason 1:
Changing the value changes the contract of it's parent.
This is also possible indirectly without changing the contract in C:
class C extends A {
public function __construct() {
$this->v = 2;
}
}
This is effectively the same thing as redeclaring it and setting a different
value for $v.
---
Reason 2:
Changing the behaviour changes the contract of it's parent.
This is also possible indirectly without changing the contract in D:
class D extends A {
private int $_v;
public function __construct() {
$this->_v = $this->v;
unset($this->v);
}
public function __set($name, $value) {
$name = "_{$name}";
$this->{$name} = $value;
}
public function __get($name) {
$name = "_{$name}";
return $this->{$name};
}
}
Thus I think since this is already possible, making it more explicit vs. this
wordy and round-about way of doing the same thing shouldn’t be necessary.
---
In both the examples above, a sibling class would still be able to access $v,
even though the default value and/or behaviour change completely. However, if
you make it more obvious that this is the case (by using hooks and/or changing
the default value), you can’t access it from a sibling.