2017-09-01 12 views
6

我有一个关于奇怪comportement的问题。调用__call而不是__callstatic在同一个类中,如果调用另一个类

看看这段代码:

class User 
{ 
    public function can($name) { 
     return call_user_func(array($name, 'test')); 
    } 

    public static function __callStatic($name, $args) { 
     return 'User::__callStatic'; 
    } 

    public function __call($name, $args) { 
     return 'User::__call'; 
    } 
} 

class Foo 
{ 
    public static function __callStatic($name, $args) { 
     return 'Foo::__callStatic'; 
    } 

    public function __call($name, $args) { 
     return 'Foo::__call?'; 
    } 
} 

$u = new User(); 
var_dump($u->can('User')); 
var_dump($u->can('Foo')); 

第一VAR转储的结果是: “用户:: __叫” 而第二个: “富:: __ callStatic”

为什么第一个不要调用函数__callStatic? PS:我看了其他话题,但没有找到解释。

感谢

+0

此代码的工作:要解决“问题”,我只能呼吁自我类的情况下,调用函数__callStatic()在我的功能can() https://3v4l.org/E1gKl – Edwin

+0

@Edwin我知道:)这不是我的问题,我希望有第一个var dump的“User :: __ callStatic” –

+0

我发布回应其他评论,现在被删除 – Edwin

回答

1

当你调用call_user_func这仅仅是一个范围问题。

当你第一次打电话can功能,你在类User上下文,它将需要__call。在第二次调用中,您的上下文来自第二课外,因此需要__callStatic。请检查callback manualcall-user-func

例如code

<?php 

class User 
{ 
    public function can($name) { 
     return call_user_func(array($name, 'test')); 
    } 

    public static function __callStatic($name, $args) { 
     return 'User::__callStatic'; 
    } 

    public function __call($name, $args) { 
     return 'User::__call'; 
    } 
} 

class Foo 
{ 
    public function can($name) { 
     return call_user_func(array($name, 'test')); 
    } 

    public static function __callStatic($name, $args) { 
     return 'Foo::__callStatic'; 
    } 

    public function __call($name, $args) { 
     return 'Foo::__call?'; 
    } 
} 

    function can($name) { 
     return call_user_func(array($name, 'test')); 
} 

$u = new User(); 
$f = new Foo(); 
var_dump($u->can('User')); 
var_dump($u->can('Foo')); 
var_dump($f->can('User')); 
var_dump($f->can('Foo')); 
var_dump(can('User')); 
var_dump(can('Foo')); 

将返回:

string(12) "User::__call" 
string(17) "Foo::__callStatic" 
string(18) "User::__callStatic" 
string(12) "Foo::__call?" 
string(18) "User::__callStatic" 
string(17) "Foo::__callStatic" 
+2

作用域是错误的词,* context *是你正在寻找的东西。然而,问题在于,为什么PHP决定'User'上下文中的'call_user_func(['User',...])是一个实例调用,而在另一个上下文中它是静态的。 – deceze

+0

是的环境比较好。如果你想使'can'函数静态,它会返回'__callStatic',所以我认为php试图首先找到同一级别的函数(如果这是有意义的)。 – Edwin

0

谢谢你们俩。

是的,这是由于背景,是PHP的一个bug(修复以后的版本中,而不是在7.2,所以...;)),或者是它只是一个陌生的comportement。

@Edwin我知道如果我将函数can()转换为静态,它会工作,但我不想。

if($name instanceof User) return self::__callStatic($functionName, $args);