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.