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

I don't think what you describe is even possible, nor would it be a good idea.

See also: https://peakd.com/hive-168588/@crell/cutting-through-the-static

--Larry Garfield

Reply via email to