On Tue, Nov 26, 2024, at 3:42 PM, Jonathan Vollebregt wrote:
On 11/26/24 9:35 PM, Larry Garfield wrote:
Thinking aloud, my expectation would be that it behaves similarly to how final static methods would behave. Which appears to be a syntax error: Online PHP editor | output for j8mp0
So, shouldn't properties do the same?
Without final you can still override both private static properties and
private static methods: Online PHP editor | output for MS73Y
When explicitly declared final, static properties do result in a syntax
error: Online PHP editor | output for fqI8v
Re-reading the logic in the original aviz RFC makes me think implicit
final here is unnecessary. All static properties are "Shadowed" like
private properties (even when they're public) so there's no conflicting
behavior.
The two behaviors described as conflicting in the aviz RFC are decided
explicitly in the context of static properties, by the caller accessing
it with `self::` or `static::`. Not by a combination of the visibility
and child classes.
Consider this example:
class A {
private(set) static int $a = 1;
public static function test(int $val) {
static::$a = $val;
}
}
class B extends A {
private(set) static int $a = 2;
}
B::test(3)
Yes this would produce a fatal error, but doing this with just `private
static` does the same in current PHP: Online PHP editor | output for Y6lZ7
You might want to discuss banning use of `static::` on private statics,
but that's a big BC break.
Since static properties do still have to have equal or wider visibility
when extending I'd say using `static::$prop` on a property you know is
private is a known risk and remove the implicit final.
- Jonathan
Hi folks. Finally getting back to this thread.
Ilija and I have discussed it, and it seems to us that the consistency of implicit-final-on-private-set (on both object and static properties) is more valuable than maximal flexibility, especially as we're dealing with a rare use case to begin with.
Specifically, `static::$prop` is still expected to behave the same as the parent class's $prop. Eg, its type can't change, its visibility cannot be narrowed, etc. So a private(set) parent $prop would violate that expectation, the same way it would for a dynamic property. Introducing another subtle difference between self:: and static:: doesn't seem like a good thing for DX.
Additionally, if we find in the future that it really would be better to not have the implicit final and allow people to "opt in" via self::vs static::, it's less of a BC break to remove the implicit final in the future than to try and introduce it.
For that reason, we are going to keep static properties consistent with object properties in this regard.
--Larry Garfield