Re: [RFC] Invoke __callStatic when non-static public methods are called statically
| From: | Rowan Tommins [IMSoP] | Date: | Mon, 01 Apr 2024 14:09:05 +0000 |
| Subject: | Re: [RFC] Invoke __callStatic when non-static public methods are called statically | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-122844@lists.php.net to get a copy of this message | ||
On 29/03/2024 18:14, Robert Landers wrote:
When generating proxies for existing types, you often need to share some state between the proxies. To do that, you put static methods/properties on the proxy class and hope to the PHP Gods that nobody will ever accidentally name something in their concrete class with the name you chose for things. To help with that, you create some kind of insane prefix.Separating static and non-static methods wouldn't solve this - the concrete class could equally add a static method with the same name but a different signature, and your generated proxy would fail to compile. In fact, exactly the same thing happens with instance methods in testing libraries: test doubles have a mixture of methods for configuring mock / spy behaviour, and methods mimicking or forwarding calls to the real interface / class. Those names could collide, and require awkward workarounds. In a statically typed language, a concrete class can have two methods with the same name, but different static types, e.g. when explicitly implementing interfaces. In a "duck typing" system like PHP's, that's much trickier, because a call to $foo->bar() doesn't have a natural way to choose which "bar" is meant.
I'd much rather see static and non-static methods being able to have the same nameAllowing this would lead to ambiguous calls, because as others have pointed out, :: doesn't always denote a static call. Consider this code: class Test { public function test() { echo 'instance test'; } public static function test() { echo 'static test'; } } class Test2 extends Test { public function runTest() { parent::test(); } } (new Test2)->runTest(); Currently, this can call either of the test() methods if you comment the other out: https://3v4l.org/5HlPE https://3v4l.org/LBALm If both are defined, which should it call? And if you wanted the other, how would you specify that? We would need some new syntax to remove the ambiguity. Regards, -- Rowan Tommins [IMSoP]