> 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

Reply via email to