2024년 3월 28일 (목) 오후 6:33, Stéphane Hulard <s.hul...@chstudio.fr>님이 작성:

> Le jeudi 28 mars 2024 à 10:40, Claude Pache <claude.pa...@gmail.com> a
> écrit :
>
> >
>
> >
>
> > > Le 28 mars 2024 à 03:29, 하늘아부지 <daddyof...@gmail.com> a écrit :
> > >
>
> > >
>
> > > Hi.
> > >
>
> > > I would like to register an RFC on the following issue.
> > > https://github.com/php/php-src/issues/13813
> > >
>
> > > To summarize briefly, users expect that the `__callStatic` magic
> method will be called in all cases when a method is not static while using
> the `__callStatic`. However, in reality, if the method is public, the
> `__callStatic` magic method is not called, and an error still occurs.
> > >
>
> > > I would like to hear your opinions.
> > > I also hope someone can help with the RFC registration.
> > >
>
> > >
>
> > > --------------------------------------------------------
> > >
>
> > > ```php
> > > <?php
> > > class MyClass
> > > {
> > > public static function __callStatic($method, $args)
> > > {
> > > echo $method . "\n";
> > > }
> > >
>
> > > private function privateMethod() {}
> > > protected function protectedMethod() {}
> > > public function publicMethod() {}
> > > }
> > >
>
> > > MyClass::privateMethod();
> > > MyClass::protectedMethod();
> > > MyClass::publicMethod();
> > > ```
> > >
>
> > > Resulted in this output:
> > > ```
> > > privateMethod
> > > protectedMethod
> > > Fatal error: Uncaught Error: Non-static method MyClass::publicMethod()
> cannot be called statically in ...
> > > ```
> > >
>
> > > But I expected this output instead:
> > > ```
> > > privateMethod
> > > protectedMethod
> > > publicMethod
> > > ```
> > >
>
> > >
>
> >
>
> >
>
> > Hi,
> > One of the issue is that it is not possible to determine statically that
> a certain call is static or not. It is possible to determine it at runtime;
> but you must be careful to articulate clearly the rules. Although it is
> absolutely possible to have logical rules, I fear that they couldn’t be
> sufficiently simple in order to avoid confusion.
> >
>
> > In the following real-world (but hopefully rare) case (it is taken from
> my own codebase), I am calling a method of a grandparent class. It is *not*
> a static method:
> >
>
> > ```php
> >
>
> > foo = new class(/* ... */) extends Bar {
> >
>
> >     // ...
> >
>
> >     function Header() {
> >         $grandparent_class = get_parent_class(parent::class);
> >         $grandparent_class::Header();
> >        // ... rest of code
> >     }
> >
>
> >    // ...
> > };
> > ```
> >
>
> > In the following more general case, I might intend to call to a static
> method. However, as of today, a call to a non-static method will occur if
>  `A` has a non-static accessible method `qux()` *and* `$this` is an
> instance of `A`:
> >
>
> > ```php
> > class Foo {
> >     function baz() {
> >         A::qux();
> >     }
> > }
> > ```
> >
>
> > (In older versions of PHP, a non-static call would occur even when
> `$this` is not an instance of `A`. Hopefully, this is no longer the case
> since PHP 8.)
> >
>
> >
>
> > —Claude
>
> Hello !
>
> In Laravel the static versus non static context is handled inside the
> different calls. So a static call on a non static method will be forwarded
> to a non static instance to be handled properly.
> I don't see any advantages to call `__callStatic` on any method call since
> the difference with `__call` is clear. Also, as Claude said, determining
> that the call is static or not is not easy.
>
> Also, building Singleton is possible using the current PHP behavior. An
> example :
>
> ```php
> <?php
>
> class User
> {
>     public function __callStatic($name, $arguments)
>     {
>         return (new static)->$name(...$arguments);
>     }
>
>     public static function __call($name, $arguments)
>     {
>         // Here handle the call the $name method.
>         echo $name;
>     }
> }
>
> $user = User::find(1);
> //Will output
> //   find
> ```
>
> That's the way it's done in Laravel. Also note that the find method
> doesn't exists in the User object. That's why it works, the method is truly
> "magic".
> If the method is defined as non static, it'll break with the error given.
>
> Stéphane
>


Hi.

I tested what Claude pointed out.
https://3v4l.org/qb6HH

>From the test results and comments by iluuu1994 on GitHub ((
https://github.com/php/php-src/issues/13813#issuecomment-2021625413), it
seems that visibility is checked first, followed by whether it's static or
not. I wonder if swapping these checks might solve the issue, but it seems
like this part will have to be left to the experts.

I understand what Stéphane pointed out. The part I'm interested in is
whether it's possible to use singletons easily without separating the
class. __call alone cannot solve this part.

For example, in Laravel, methods defined in the DB class can be called
through __callStatic in the Model class, but methods defined in the Model
class or classes inheriting from the Model class cannot be called using ::.
Therefore, scope-related methods must be implemented using a scope prefix.
You're using scopeKeyword methods like User::keyword. I think this awkward
usage and the grotesque form that arose because __callStatic is not called
in the case of all public methods.

daddyofsky

Reply via email to