Re: [RFC] Static property asymmetric visibility

From: Date: Mon, 30 Dec 2024 20:38:29 +0000
Subject: Re: [RFC] Static property asymmetric visibility
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
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:  https://3v4l.org/j8mp0#v8.4.1
>> 
>> So, shouldn't properties do the same?
>
> Without final you can still override both private static properties and 
> private static methods: https://3v4l.org/MS73Y#v8.4.1
>
> When explicitly declared final, static properties do result in a syntax 
> error: https://3v4l.org/fqI8v#v8.4.1
>
> 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: https://3v4l.org/Y6lZ7#v8.4.1
>
> 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


Thread (11 messages)

« previous php.internals (#126190) next »