> Le 17 févr. 2024 à 16:51, Larry Garfield <la...@garfieldtech.com> a écrit :
>
> On Fri, Feb 16, 2024, at 7:56 PM, 하늘아부지 wrote:
>> Hi.
>> I'd like to propose an RFC, but I don't have the authority.
>> Below is my suggestion.
>> If you think this makes sense, please write an RFC for me.
>> Sincerely.
>>
>> ----------------------------------------------------------
>>
>> ===== Introduction =====
>> Allows calling non-static public methods through the __callStatic magic
>> method instead of throwing an error.
>>
>> ===== Proposal =====
>>
>> From a conceptual perspective:
>> It goes without saying that calling a non-static method statically will
>> result in an error.
>> However, a confusing situation occurred when the __callStatic magic
>> method exists.
>> Non-public methods can be called, but public methods cannot.
>> This is the opposite of the method visibility policy.
>>
>> From a practical point of view:
>> If you can call Non-static public methods through the __callStatic
>> magic method, you can write code like Laravel ORM more simply and tidy.
>>
>> <code>
>> User::foo()->bar();
>> </code>
>>
>> ==== Before ====
>>
>> <code>
>> class Foo
>> {
>> protected static ?Foo $instance = null;
>>
>> public static function __callStatic($method, $args)
>> {
>> $instance = self::$instance ?? self::$instance = new static();
>> return $instance->__call($method, $args);
>> }
>>
>> public function __call($method, $args)
>> {
>> if (method_exists($this, $method)) {
>> return $instance->$method(...$args);
>> }
>>
>> return $this;
>> }
>>
>> protected function bar()
>> {
>> echo __METHOD__ . '<br />';
>>
>> return $this;
>> }
>>
>> protected function baz()
>> {
>> echo __METHOD__ . '<br />';
>>
>> return $this;
>> }
>> }
>>
>> Foo::bar()->baz();
>> (new Foo())->bar()->baz();
>> </code>
>>
>> There is no error, but the concept of method visibility is broken.
>> All Non-public methods can be called at instance scope.
>>
>> ==== After ====
>>
>> <code>
>> class Foo
>> {
>> protected static ?Foo $instance = null;
>>
>> public static function __callStatic($method, $args)
>> {
>> $instance = self::$instance ?? self::$instance = new static();
>>
>> if (method_exists($instance, $method)) {
>> return $instance->$method(...$args);
>> }
>>
>> return $instance;
>> }
>>
>> public function bar()
>> {
>> echo __METHOD__ . '<br />';
>>
>> return $this;
>> }
>>
>> public function baz()
>> {
>> echo __METHOD__ . '<br />';
>>
>> return $this;
>> }
>> }
>>
>> Foo::bar()->baz();
>> (new Foo())->bar()->baz();
>> </code>
>>
>> This is more tidy.
>> Only public methods are callable at instance scope.
>
> That calling bar() works at all in this example is rather accidental. The
> whole point of a non-static method is that it has an implicit required $this
> argument to it. Without a required argument, a method cannot be called,
> because it is supposed to fail.
>
> In fact, even your "before" example fails: https://3v4l.org/moH0s
It does work after having corrected the obvious bug in the `bar()` method.
>
> I don't think what you describe is even possible, nor would it be a good idea.
Why wouldn’t it possible? Couldn’t the engine invoke __callStatic() instead of
complaining that the targeted method is not static? (I don’t have opinion on
whether it is a good idea, though)
—Claude