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