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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to