RFC Proposal : Allows calling non-static public methods through the __callStatic magic method instead of throwing an error.
| From: | 하늘아부지 | Date: | Sat, 17 Feb 2024 01:56:00 +0000 |
| Subject: | RFC Proposal : Allows calling non-static public methods through the __callStatic magic method instead of throwing an error. | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-122403@lists.php.net to get a copy of this message | ||
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.