PHP Late Static Binding引用调用类

Sch*_*eis 2 php late-static-binding

我有一个静态函数被调用,它给出了一个奇怪的错误.这是一个PHP代码的例子:

class foo {
     public $stat;
     public function __construct() {
         $this->stat = stat::isValid('two');
     }
}

class stat {
     protected static $invalidNumbers = array('one', 'two');
     function isValid($number) {
         return in_array($number, static::$invalidNumbers);
     }
}

$foo = new foo();
var_dump($foo->stat);
Run Code Online (Sandbox Code Playgroud)

此代码导致以下错误:

Fatal error: Access to undeclared static property: foo::$invalidNumbers
Run Code Online (Sandbox Code Playgroud)

但是,更改static::self::使代码按预期运行.我的印象是在这种情况下使用static::应该起作用.

为什么会出现此错误static

Jon*_*Jon 6

首先在静态上下文中进行方法调用:

stat::isValid('two');
Run Code Online (Sandbox Code Playgroud)

执行此操作时,PHP会"记住" isValid特定调用的上下文,以便在它看到类似于static::方法体内的内容时,可以解析要绑定的内容,确定您尝试访问的某些属性是否可见,以及一般能够实现一些与OO相关的语言功能.

实际的方法isValid没有 static的,但PHP仍允许您使用静态方法语法来调用它(它确实给一个E_STRICT警告有关).然而,这具有副作用,isValid其本身不参与修改(后期)静态绑定的临时调用上下文.

结果:当PHP看到static::$invalidNumbers,它仍然认为你正在从foo类中进行静态方法调用!一旦你意识到这一点,很明显为什么要static::解决foo::它并最终在错误的地方寻找财产.

如果你正确地声明isValidstatic

 static function isValid($number) {
     return in_array($number, static::$invalidNumbers);
 }
Run Code Online (Sandbox Code Playgroud)

然后在调用方法时,PHP 在内部更新其上下文并设法绑定到目标成员.