Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
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 name Allowing 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]
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On 29/03/2024 02:39, 하늘아부지 wrote: I created a wiki for __callStatic related issues. Please see: https://wiki.php.net/rfc/complete_callstatc_magic Hi, Several times in the discussion you have said (in different words) "__callStatic is called for instance methods which are private or protected", but that is not how it is generally interpreted. If you are calling a method from outside the class, as far as you're concerned only public methods exist; private methods are, by definition, hidden implementation details. This is more obvious in languages with static typing, where if you have an instance of some interface, only the methods on that interface exist; the concrete object might actually have other methods, but you can't access them. That is what is meant by "inaccessible": __call and __callStatic are called for methods which, as seen from the current scope, *do not exist*. You could still argue that static context is like a different scope, or a different statically typed interface - as far as that context is concerned, only static methods exist. But that's also not a common interpretation, for (at least) two reasons: Firstly, there is no syntax in PHP which specifically marks a static call - Foo::bar() is used for both static calls, and for forwarding instance calls, most obviously in the case of parent::foo(). Secondly, until PHP 8, marking a method as static was optional; an error was only raised once you tried to access $this in a context where it wasn't defined. In PHP 4, this was correct code; in PHP 5 and 7, it raised diagnostics (first E_STRICT, later E_DEPRECATED) but still ran the method: class Foo { function bar() { echo 'Hello, World!'; } } Foo::bar(); I think that's part of the reason you're getting negative feedback: to you, the feature seems like an obvious extension, even a bug fix; but to others, it seems like a complete change to how static calls are interpreted. Regards, -- Rowan Tommins [IMSoP]
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
2024년 4월 1일 (월) 오전 2:31, Larry Garfield 님이 작성: > On Fri, Mar 29, 2024, at 6:12 PM, 하늘아부지 wrote: > > >> It would be more accurate to say "calling non-static methods in a > static-like manner is common *in Laravel* > > > > It might be correct to say that this is specific to Laravel. The > > problem, however, is that Laravel is used so extensively that it cannot > > be ignored. > > True, but as someone else noted, Laravel already has a workaround in place > for this. WordPress is orders of magnitude more popular than Laravel, but > we don't generally design the language to work "the WordPress way," because > that is well-recognized as a not-good way to work. > > Popularity matters, but quality matters more. > > > There's a point of embarrassing me. It's as if my proposal, if > > accepted, would create problems that did not previously exist. Yet, the > > existence of `__callStatic` already allows for the issues you've > > pointed out to occur. You can already write code like > > `foo::bar()::baz()` with the current PHP. The possibility of more > > problems arising could indeed be true. In that sense, I understand your > > point. > > To be clear: I have no interest or desire to embarrass you personally. I > have never met you before so have no opinion about you one way or another, > and trust the feeling is mutual. That you're interested in improving PHP > is to your credit, and I thank you for that. > > However, that is separate from the proposal itself, which for reasons > stated I think is not a good one. That should not reflect on you > personally in any way, and is explicitly not intended as such. Certainly > I've had enough of my proposals rejected around here. :-) > > --Larry Garfield > I understand. I didn't assume my proposal would be accepted without question. I just started because I hate doing nothing. Daddyofsky
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On Fri, Mar 29, 2024, at 6:12 PM, 하늘아부지 wrote: >> It would be more accurate to say "calling non-static methods in a >> static-like manner is common *in Laravel* > > It might be correct to say that this is specific to Laravel. The > problem, however, is that Laravel is used so extensively that it cannot > be ignored. True, but as someone else noted, Laravel already has a workaround in place for this. WordPress is orders of magnitude more popular than Laravel, but we don't generally design the language to work "the WordPress way," because that is well-recognized as a not-good way to work. Popularity matters, but quality matters more. > There's a point of embarrassing me. It's as if my proposal, if > accepted, would create problems that did not previously exist. Yet, the > existence of `__callStatic` already allows for the issues you've > pointed out to occur. You can already write code like > `foo::bar()::baz()` with the current PHP. The possibility of more > problems arising could indeed be true. In that sense, I understand your > point. To be clear: I have no interest or desire to embarrass you personally. I have never met you before so have no opinion about you one way or another, and trust the feeling is mutual. That you're interested in improving PHP is to your credit, and I thank you for that. However, that is separate from the proposal itself, which for reasons stated I think is not a good one. That should not reflect on you personally in any way, and is explicitly not intended as such. Certainly I've had enough of my proposals rejected around here. :-) --Larry Garfield
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On Sat, Mar 30, 2024 at 1:06 AM 하늘아부지 wrote: > > > > 2024년 3월 30일 (토) 오전 2:15, Robert Landers 님이 작성: >> >> On Fri, Mar 29, 2024 at 3:41 AM 하늘아부지 wrote: >> > >> > Hello. >> > >> > I created a wiki for __callStatic related issues. >> > Please see: >> > https://wiki.php.net/rfc/complete_callstatc_magic >> > >> > I look forward to your interest and advice. >> > >> > Best Regards. >> > Daddyofsky >> >> Hey there, >> >> Some general feedback: >> >> The RFC is a bit hard for me to follow, for example: >> >> > However, the IDE cannot find active method, and the Go to Definition >> > feature cannot be used. >> >> This sounds like a bug or feature request with your IDE, not a problem with >> PHP. >> >> > This code is very clear, aside from the fact that the method is not static. >> >> Clear to whom? As a developer this looks downright confusing. I can't >> even guess what the actual behavior is. If you call a non-static >> method statically, its currently an error. Why would this not be an >> error? >> >> > The IDE recognizes active methods well and the Go to definition feature >> > also works properly. >> >> What is stopping the IDE to taking you to the __callStatic method? >> That would be the correct behavior IMHO, not the implementation for >> instance methods. >> >> > Even if there are only a few core methods, it cannot be made into a single >> > file. >> >> There is nothing stopping you from putting multiple classes in a file. >> >> > As can be seen in the above examples, the code becomes clearer, and >> > navigation through the IDE works much better. >> >> I completely disagree. It mixes concerns and makes spaghetti code into >> incomprehensible code. Also, maybe you should take up IDE navigation >> with your IDE? >> >> > Instead of throwing an error when a non-static public method is called >> > statically, the _ _callStatic method should be invoked. >> >> I completely agree with this, btw. Your examples could use some work >> and shows all the reasons why it shouldn't call __callStatic(). A real >> life example, that has nothing to do with a specific framework: >> >> 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. If __callStatic() were called ALWAYS in a >> static context, even if a non-static method exists, then collisions >> would literally be impossible. But at that point, why can't I just >> write: >> >> class Test { >> public static function test(): string { return "hello world"; } >> public function test(): int { return random_int(); } >> } >> >> ??? I feel like this is your real RFC and should be allowed if we're >> allowed to __callStatic() to instance methods. I don't think it makes >> sense to have one without the other, and then what you want with >> __callStatic() comes naturally, instead of this weird and confusing >> RFC. >> >> >> Robert Landers >> Software Engineer >> Utrecht NL > > > Hello. > > I'm not very familiar with documentation. It would be helpful if you could > suggest how to fix the problematic parts. > > Using the example of the IDE meant to illustrate that it should be intuitive > enough for the IDE to find it directly. > > Even currently, `__callStatic` is called in cases of non-static methods that > are not public methods. `__callStatic` already acts as a rule-breaker. It > seems like there's a desire for the magic method to be named as such without > actually causing much magic. The current `__callStatic` is like a magician > who can use high-level magic to hit targets behind doors or invisible targets > but can't use basic magic to hit a visible door. > > While it's good that the PHP kindly notifies errors, I think it would also be > beneficial to provide users with options to do other things, specifically > when they intentionally use `__callStatic`. That's the core point of this > proposal. > > If there are better examples or ways to explain, I would appreciate learning > about them. > > Daddyofsky My main issue with the RFC comes down to the fact that it suggests that this is valid: // https://3v4l.org/0ufkt class Test { public function test() {} public static function test() {} } Having two functions with the same name, one static and one non-static is (currently) an error. Allowing callStatic to break this rule without being able to write the above code, feels inconsistent. While PHP is full of inconsistencies, adding more of them isn't the right way. I'd much rather see static and non-static methods being able to have the same name -- in which case it would make sense for callStatic to work as described in the RFC. Robert Landers Software Engineer Utrecht NL
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On 2024-03-30 13:06, 하늘아부지 wrote: Even currently, `__callStatic` is called in cases of non-static methods that are not public methods. `__callStatic` already acts as a rule-breaker. I think the problem here is a confusion based on the idea that there is necessarily some direct correspondence between method names and strings passed to __callStatic. It's like confusing URLs with file paths. The fact that an object *may* have a private method named "foo" doesn't have any bearing on whether classname::foo() invokes __callStatic('foo') or not. The existence or otherwise of such methods in the class is irrelevant. __callStatic receives a string, and what it does with that string is entirely up to whoever is writing it. class First { protected static function test(): string { return "Calling First::test\n"; } } class Second extends First { public static function __callStatic(string $name, array $args): string { return "Calling callStatic::$name\n"; } public static function pass(): string { return Second::test(); // The inherited method } } echo Second::pass(); echo Second::test(); // Not the inherited method
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
2024년 3월 30일 (토) 오전 2:15, Robert Landers 님이 작성: > On Fri, Mar 29, 2024 at 3:41 AM 하늘아부지 wrote: > > > > Hello. > > > > I created a wiki for __callStatic related issues. > > Please see: > > https://wiki.php.net/rfc/complete_callstatc_magic > > > > I look forward to your interest and advice. > > > > Best Regards. > > Daddyofsky > > Hey there, > > Some general feedback: > > The RFC is a bit hard for me to follow, for example: > > > However, the IDE cannot find active method, and the Go to Definition > feature cannot be used. > > This sounds like a bug or feature request with your IDE, not a problem > with PHP. > > > This code is very clear, aside from the fact that the method is not > static. > > Clear to whom? As a developer this looks downright confusing. I can't > even guess what the actual behavior is. If you call a non-static > method statically, its currently an error. Why would this not be an > error? > > > The IDE recognizes active methods well and the Go to definition feature > also works properly. > > What is stopping the IDE to taking you to the __callStatic method? > That would be the correct behavior IMHO, not the implementation for > instance methods. > > > Even if there are only a few core methods, it cannot be made into a > single file. > > There is nothing stopping you from putting multiple classes in a file. > > > As can be seen in the above examples, the code becomes clearer, and > navigation through the IDE works much better. > > I completely disagree. It mixes concerns and makes spaghetti code into > incomprehensible code. Also, maybe you should take up IDE navigation > with your IDE? > > > Instead of throwing an error when a non-static public method is called > statically, the _ _callStatic method should be invoked. > > I completely agree with this, btw. Your examples could use some work > and shows all the reasons why it shouldn't call __callStatic(). A real > life example, that has nothing to do with a specific framework: > > 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. If __callStatic() were called ALWAYS in a > static context, even if a non-static method exists, then collisions > would literally be impossible. But at that point, why can't I just > write: > > class Test { > public static function test(): string { return "hello world"; } > public function test(): int { return random_int(); } > } > > ??? I feel like this is your real RFC and should be allowed if we're > allowed to __callStatic() to instance methods. I don't think it makes > sense to have one without the other, and then what you want with > __callStatic() comes naturally, instead of this weird and confusing > RFC. > > > Robert Landers > Software Engineer > Utrecht NL > Hello. I'm not very familiar with documentation. It would be helpful if you could suggest how to fix the problematic parts. Using the example of the IDE meant to illustrate that it should be intuitive enough for the IDE to find it directly. Even currently, `__callStatic` is called in cases of non-static methods that are not public methods. `__callStatic` already acts as a rule-breaker. It seems like there's a desire for the magic method to be named as such without actually causing much magic. The current `__callStatic` is like a magician who can use high-level magic to hit targets behind doors or invisible targets but can't use basic magic to hit a visible door. While it's good that the PHP kindly notifies errors, I think it would also be beneficial to provide users with options to do other things, specifically when they intentionally use `__callStatic`. That's the core point of this proposal. If there are better examples or ways to explain, I would appreciate learning about them. Daddyofsky
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
2024년 3월 30일 (토) 오전 1:21, Larry Garfield 님이 작성: > On Fri, Mar 29, 2024, at 3:33 PM, 하늘아부지 wrote: > > 2024년 3월 29일 (금) 오후 10:21, Larry Garfield 님이 작성: > >> On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote: > >> > Hello. > >> > > >> > I created a wiki for __callStatic related issues. > >> > Please see: > >> > https://wiki.php.net/rfc/complete_callstatc_magic > >> > I look forward to your interest and advice. > >> > >> I am firmly against this proposal. > >> > >> I think my objection boils down to this line in the RFC: > >> > >> > Of course, calling non-static methods in a static-like manner can be > confusing, but in modern PHP, it has already become common practice. > >> > >> I would argue this statement is false. Calling non-static methods in a > static-like manner is confusing, which is why in modern PHP one should > never do that, and respect that static and non-static methods exist in a > separate universe. Static methods are methods *on a type*. Non-static > methods are methods *on an instance*. Those are not the same thing.[1] > >> > >> It would be more accurate to say "calling non-static methods in a > static-like manner is common *in Laravel*," where the badly-named "facades" > system serves as a poorly designed, hard to debug, hard to test, archaic > alternative to using dependency injection. While there may have once been > an argument that DI was "too hard" for simple cases a decade ago or more > (though even then I think it was a bade trade-off), the combination of > auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor > promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates > those arguments. The level of effort to do actual DI today is trivially > small, and the benefits over magic hidden globals are massive. > >> > >> Laravel Facades are a relic of an older time best avoided, even in > Laravel projects. (I am far from the only person to argue this; many even > within Laravel's inner community make this argument.) > >> > >> Adding features to the language that seemingly exist only to make that > particular buggy hack easier to do is a step backwards, and I would argue > harmful for the language. On the contrary, I would favor going the other > direction: Calling a static method as though it were non-static currently > works, and I would support making that an error, to further emphasize that > static and non-static methods are not interchangeable. > >> > >> [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static > >> > >> --Larry Garfield > > > > Thank you for your feedback. > > I agree that static and non-static should be distinct, which is a given. > > > > There are a few points I'd like to make. > > > > First, my proposed RFC is not about allowing non-static methods to be > > used statically. Although all my examples use `::`, they internally > > operate on an instance. Inside `__callStatic`, an instance is created > > and used for operations. > > > > Second, as already possible through the `__callStatic` method, > > non-static methods can be called as if they were static (as mentioned, > > this does not mean they operate statically). For protected and private > > methods, the `__callStatic` function is invoked even for non-static > > methods. This might not be to everyone's liking, and to others, it > > might be a favorite feature. It might operate differently from the > > initial intention when `__callStatic` was introduced. However, I don't > > think this is necessarily a bad thing. Isn't it developers who bring to > > life ingenious ideas that were unforeseen? > > Developers also bring to life horrible monstrosities that are an afront to > all that is holy. I am a developer. It's what we do. :-) Especially when > VC money is involved. > > Not all "innovation" is good. > > > Third, as you can see from my examples, what I propose could be a > > solution to the current issues. Since it does not work for public > > methods while it does for protected and private ones, it has led to > > code becoming more obscure and layered through facade-like patterns. > > It's like taking a longer route because the road is blocked, or > > creating a dog door because the main door is closed. > > It simplifies a practice that should not be a practice in the first > place. That's not a net-win. > > > From the perspective of those who develop the PHP language itself, my > > proposal might not be appealing. However, I believe from the user's > > standpoint, my proposal could lead to more convenient and cleaner > > coding practices. Didn't PHP start as a language meant to be > > user-friendly? > > I don't actually work on the PHP engine, I just write RFC text for other > people; I have ~25 years of experience writing user-space PHP. And no, > anything involving stealth globals via statics is the opposite of "more > convenient and cleaner." > > --Larry Garfield > Hi. > It would be more accurate to say "calling non-static methods in a static-like
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On Fri, Mar 29, 2024 at 3:41 AM 하늘아부지 wrote: > > Hello. > > I created a wiki for __callStatic related issues. > Please see: > https://wiki.php.net/rfc/complete_callstatc_magic > > I look forward to your interest and advice. > > Best Regards. > Daddyofsky Hey there, Some general feedback: The RFC is a bit hard for me to follow, for example: > However, the IDE cannot find active method, and the Go to Definition feature > cannot be used. This sounds like a bug or feature request with your IDE, not a problem with PHP. > This code is very clear, aside from the fact that the method is not static. Clear to whom? As a developer this looks downright confusing. I can't even guess what the actual behavior is. If you call a non-static method statically, its currently an error. Why would this not be an error? > The IDE recognizes active methods well and the Go to definition feature also > works properly. What is stopping the IDE to taking you to the __callStatic method? That would be the correct behavior IMHO, not the implementation for instance methods. > Even if there are only a few core methods, it cannot be made into a single > file. There is nothing stopping you from putting multiple classes in a file. > As can be seen in the above examples, the code becomes clearer, and > navigation through the IDE works much better. I completely disagree. It mixes concerns and makes spaghetti code into incomprehensible code. Also, maybe you should take up IDE navigation with your IDE? > Instead of throwing an error when a non-static public method is called > statically, the _ _callStatic method should be invoked. I completely agree with this, btw. Your examples could use some work and shows all the reasons why it shouldn't call __callStatic(). A real life example, that has nothing to do with a specific framework: 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. If __callStatic() were called ALWAYS in a static context, even if a non-static method exists, then collisions would literally be impossible. But at that point, why can't I just write: class Test { public static function test(): string { return "hello world"; } public function test(): int { return random_int(); } } ??? I feel like this is your real RFC and should be allowed if we're allowed to __callStatic() to instance methods. I don't think it makes sense to have one without the other, and then what you want with __callStatic() comes naturally, instead of this weird and confusing RFC. Robert Landers Software Engineer Utrecht NL
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On 29.03.2024 14:03, Larry Garfield wrote: On the contrary, I would favor going the other direction: Calling a static method as though it were non-static currently works, and I would support making that an error, to further emphasize that static and non-static methods are not interchangeable. It's side-tracking, but I'd like to note that I would vote against such an idea. I don't have a strong opinion on the proposed RFC yet. -- Aleksander Machniak Kolab Groupware Developer[https://kolab.org] Roundcube Webmail Developer [https://roundcube.net] PGP: 19359DC1 # Blog: https://kolabian.wordpress.com
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On Fri, Mar 29, 2024, at 3:33 PM, 하늘아부지 wrote: > 2024년 3월 29일 (금) 오후 10:21, Larry Garfield 님이 작성: >> On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote: >> > Hello. >> > >> > I created a wiki for __callStatic related issues. >> > Please see: >> > https://wiki.php.net/rfc/complete_callstatc_magic >> > I look forward to your interest and advice. >> >> I am firmly against this proposal. >> >> I think my objection boils down to this line in the RFC: >> >> > Of course, calling non-static methods in a static-like manner can be >> > confusing, but in modern PHP, it has already become common practice. >> >> I would argue this statement is false. Calling non-static methods in a >> static-like manner is confusing, which is why in modern PHP one should never >> do that, and respect that static and non-static methods exist in a separate >> universe. Static methods are methods *on a type*. Non-static methods are >> methods *on an instance*. Those are not the same thing.[1] >> >> It would be more accurate to say "calling non-static methods in a >> static-like manner is common *in Laravel*," where the badly-named "facades" >> system serves as a poorly designed, hard to debug, hard to test, archaic >> alternative to using dependency injection. While there may have once been >> an argument that DI was "too hard" for simple cases a decade ago or more >> (though even then I think it was a bade trade-off), the combination of >> auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor >> promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates >> those arguments. The level of effort to do actual DI today is trivially >> small, and the benefits over magic hidden globals are massive. >> >> Laravel Facades are a relic of an older time best avoided, even in Laravel >> projects. (I am far from the only person to argue this; many even within >> Laravel's inner community make this argument.) >> >> Adding features to the language that seemingly exist only to make that >> particular buggy hack easier to do is a step backwards, and I would argue >> harmful for the language. On the contrary, I would favor going the other >> direction: Calling a static method as though it were non-static currently >> works, and I would support making that an error, to further emphasize that >> static and non-static methods are not interchangeable. >> >> [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static >> >> --Larry Garfield > > Thank you for your feedback. > I agree that static and non-static should be distinct, which is a given. > > There are a few points I'd like to make. > > First, my proposed RFC is not about allowing non-static methods to be > used statically. Although all my examples use `::`, they internally > operate on an instance. Inside `__callStatic`, an instance is created > and used for operations. > > Second, as already possible through the `__callStatic` method, > non-static methods can be called as if they were static (as mentioned, > this does not mean they operate statically). For protected and private > methods, the `__callStatic` function is invoked even for non-static > methods. This might not be to everyone's liking, and to others, it > might be a favorite feature. It might operate differently from the > initial intention when `__callStatic` was introduced. However, I don't > think this is necessarily a bad thing. Isn't it developers who bring to > life ingenious ideas that were unforeseen? Developers also bring to life horrible monstrosities that are an afront to all that is holy. I am a developer. It's what we do. :-) Especially when VC money is involved. Not all "innovation" is good. > Third, as you can see from my examples, what I propose could be a > solution to the current issues. Since it does not work for public > methods while it does for protected and private ones, it has led to > code becoming more obscure and layered through facade-like patterns. > It's like taking a longer route because the road is blocked, or > creating a dog door because the main door is closed. It simplifies a practice that should not be a practice in the first place. That's not a net-win. > From the perspective of those who develop the PHP language itself, my > proposal might not be appealing. However, I believe from the user's > standpoint, my proposal could lead to more convenient and cleaner > coding practices. Didn't PHP start as a language meant to be > user-friendly? I don't actually work on the PHP engine, I just write RFC text for other people; I have ~25 years of experience writing user-space PHP. And no, anything involving stealth globals via statics is the opposite of "more convenient and cleaner." --Larry Garfield
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
2024년 3월 29일 (금) 오후 10:21, Larry Garfield 님이 작성: > On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote: > > Hello. > > > > I created a wiki for __callStatic related issues. > > Please see: > > https://wiki.php.net/rfc/complete_callstatc_magic > > I look forward to your interest and advice. > > I am firmly against this proposal. > > I think my objection boils down to this line in the RFC: > > > Of course, calling non-static methods in a static-like manner can be > confusing, but in modern PHP, it has already become common practice. > > I would argue this statement is false. Calling non-static methods in a > static-like manner is confusing, which is why in modern PHP one should > never do that, and respect that static and non-static methods exist in a > separate universe. Static methods are methods *on a type*. Non-static > methods are methods *on an instance*. Those are not the same thing.[1] > > It would be more accurate to say "calling non-static methods in a > static-like manner is common *in Laravel*," where the badly-named "facades" > system serves as a poorly designed, hard to debug, hard to test, archaic > alternative to using dependency injection. While there may have once been > an argument that DI was "too hard" for simple cases a decade ago or more > (though even then I think it was a bade trade-off), the combination of > auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor > promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates > those arguments. The level of effort to do actual DI today is trivially > small, and the benefits over magic hidden globals are massive. > > Laravel Facades are a relic of an older time best avoided, even in Laravel > projects. (I am far from the only person to argue this; many even within > Laravel's inner community make this argument.) > > Adding features to the language that seemingly exist only to make that > particular buggy hack easier to do is a step backwards, and I would argue > harmful for the language. On the contrary, I would favor going the other > direction: Calling a static method as though it were non-static currently > works, and I would support making that an error, to further emphasize that > static and non-static methods are not interchangeable. > > [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static > > --Larry Garfield > Thank you for your feedback. I agree that static and non-static should be distinct, which is a given. There are a few points I'd like to make. First, my proposed RFC is not about allowing non-static methods to be used statically. Although all my examples use `::`, they internally operate on an instance. Inside `__callStatic`, an instance is created and used for operations. Second, as already possible through the `__callStatic` method, non-static methods can be called as if they were static (as mentioned, this does not mean they operate statically). For protected and private methods, the `__callStatic` function is invoked even for non-static methods. This might not be to everyone's liking, and to others, it might be a favorite feature. It might operate differently from the initial intention when `__callStatic` was introduced. However, I don't think this is necessarily a bad thing. Isn't it developers who bring to life ingenious ideas that were unforeseen? Third, as you can see from my examples, what I propose could be a solution to the current issues. Since it does not work for public methods while it does for protected and private ones, it has led to code becoming more obscure and layered through facade-like patterns. It's like taking a longer route because the road is blocked, or creating a dog door because the main door is closed. >From the perspective of those who develop the PHP language itself, my proposal might not be appealing. However, I believe from the user's standpoint, my proposal could lead to more convenient and cleaner coding practices. Didn't PHP start as a language meant to be user-friendly? Regards Daddyofsky
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote: > Hello. > > I created a wiki for __callStatic related issues. > Please see: > https://wiki.php.net/rfc/complete_callstatc_magic > I look forward to your interest and advice. I am firmly against this proposal. I think my objection boils down to this line in the RFC: > Of course, calling non-static methods in a static-like manner can be > confusing, but in modern PHP, it has already become common practice. I would argue this statement is false. Calling non-static methods in a static-like manner is confusing, which is why in modern PHP one should never do that, and respect that static and non-static methods exist in a separate universe. Static methods are methods *on a type*. Non-static methods are methods *on an instance*. Those are not the same thing.[1] It would be more accurate to say "calling non-static methods in a static-like manner is common *in Laravel*," where the badly-named "facades" system serves as a poorly designed, hard to debug, hard to test, archaic alternative to using dependency injection. While there may have once been an argument that DI was "too hard" for simple cases a decade ago or more (though even then I think it was a bade trade-off), the combination of auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates those arguments. The level of effort to do actual DI today is trivially small, and the benefits over magic hidden globals are massive. Laravel Facades are a relic of an older time best avoided, even in Laravel projects. (I am far from the only person to argue this; many even within Laravel's inner community make this argument.) Adding features to the language that seemingly exist only to make that particular buggy hack easier to do is a step backwards, and I would argue harmful for the language. On the contrary, I would favor going the other direction: Calling a static method as though it were non-static currently works, and I would support making that an error, to further emphasize that static and non-static methods are not interchangeable. [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static --Larry Garfield
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
2024년 3월 29일 (금) 오후 5:43, Stéphane Hulard 님이 작성: > Le vendredi 29 mars 2024 à 03:39, 하늘아부지 a écrit : > > > Hello. > > > > > I created a wiki for __callStatic related issues. > > Please see: > > https://wiki.php.net/rfc/complete_callstatc_magic > > > > > I look forward to your interest and advice. > > > > > Best Regards. > > Daddyofsky > > Hello ! > > I took a look at your proposal and I think about important issues if we go > this way. > > A static method mustn't used the `$this` variable because it simply > doesn't exists in the static context. The examples you're adding in the RFC > are fine but they always rely to a specific `__callStatic` implementation > that will use a new instance of the object to forward the call. > > There are multiple cases where it'll be complicated to use it this way. > Two of them I have in mind: > > - What if the object needs important parameters in its constructor that > aren't available in the static context ? Or those parameters need to be > initialized outside of the `__callStatic` method? > - What if the underlying non static method we are trying to invoke is > using the `$this` variable? > > In those two examples, I would prefer having a fatal error that explains > that I'm not doing the call correctly (calling a non static method in the > static context) to ensure it'll be easy to understand and fix. > > The use cases you are describing here have been fixed in the user space by > the Laravel team. It's a very specific way of working that's mostly > specific to Laravel. > > For sure it makes the code harder to read since you can't jump to a real > method easily (because most of the methods are magic ones and are forwarded > to underlying objects). I don't tell it's wrong but I'm not sure it's > relevant to make the whole language simplify this process. > > If there is a way to work correctly with those static vs non static calls > and capture relevant errors to expose them to users, that's fine. > > However, I think this is an important behavior change because it'll allow > a new way to work with method that were forbidden before. > > Regards > Stéphane Hello. Thank you for your interest. In fact, `__callStatic` is often used for static-like singletons, and such examples are likely to be the majority. Regarding the two issues you pointed out, the first can be resolved by adding an initialization method like `init`. It's common to use a separate initialization function when dealing with general class operations, especially when there is a lot to initialize. The second issue is actually the same problem that exists today. Since `__callStatic` is called in the case of static calls to private or protected methods, the use of `$this` is not exclusive to public methods. In other words, the `$this` issue applies the same way it does now. Allowing public methods does not create a problem that didn't exist before. If it had been the case that calling non-static methods statically always resulted in an error, the issues you raised would have been significant. However, private and protected methods can already be called without error. Even if this RFC is not accepted, the points you mentioned still apply. Regards Daddyofsky
Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
Le vendredi 29 mars 2024 à 03:39, 하늘아부지 a écrit : > Hello. > > I created a wiki for __callStatic related issues. > Please see: > https://wiki.php.net/rfc/complete_callstatc_magic > > I look forward to your interest and advice. > > Best Regards. > Daddyofsky Hello ! I took a look at your proposal and I think about important issues if we go this way. A static method mustn't used the `$this` variable because it simply doesn't exists in the static context. The examples you're adding in the RFC are fine but they always rely to a specific `__callStatic` implementation that will use a new instance of the object to forward the call. There are multiple cases where it'll be complicated to use it this way. Two of them I have in mind: - What if the object needs important parameters in its constructor that aren't available in the static context ? Or those parameters need to be initialized outside of the `__callStatic` method? - What if the underlying non static method we are trying to invoke is using the `$this` variable? In those two examples, I would prefer having a fatal error that explains that I'm not doing the call correctly (calling a non static method in the static context) to ensure it'll be easy to understand and fix. The use cases you are describing here have been fixed in the user space by the Laravel team. It's a very specific way of working that's mostly specific to Laravel. For sure it makes the code harder to read since you can't jump to a real method easily (because most of the methods are magic ones and are forwarded to underlying objects). I don't tell it's wrong but I'm not sure it's relevant to make the whole language simplify this process. If there is a way to work correctly with those static vs non static calls and capture relevant errors to expose them to users, that's fine. However, I think this is an important behavior change because it'll allow a new way to work with method that were forbidden before. Regards Stéphane signature.asc Description: OpenPGP digital signature
[PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically
Hello. I created a wiki for __callStatic related issues. Please see: https://wiki.php.net/rfc/complete_callstatc_magic I look forward to your interest and advice. Best Regards. Daddyofsky