PHP Late Static Binding引用调用类

时间:2013-04-25 20:24:37

标签: 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);

此代码导致以下错误:

Fatal error: Access to undeclared static property: foo::$invalidNumbers

但是,将static::更改为self::会使代码按预期运行。我的印象是在这种情况下使用static::应该有用。

为什么使用static会发生此错误?

3 个答案:

答案 0 :(得分:6)

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

stat::isValid('two');

执行此操作时,PHP会“记住”特定调用isValid的上下文,以便在方法正文中看到static::之类的内容时,可以解析绑定到的内容,确定如果您尝试访问的某些属性是可见的,并且通常能够实现一些与OO相关的语言功能。

实际方法isValid static,但PHP仍然允许您使用静态方法语法调用它(它确实会发出E_STRICT警告关于那个)。但是,这有副作用,isValid本身不参与修改(后期)静态绑定的临时调用上下文。

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

如果您正确地将isValid声明为static

 static function isValid($number) {
     return in_array($number, static::$invalidNumbers);
 }

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

答案 1 :(得分:3)

您尝试静态调用方法stat::isValid()但尚未声明static。将stat课程更改为:

class stat {
     protected static $invalidNumbers = array('one', 'two');

     // needs to be declared static
     static function isValid($number) {
         return in_array($number, static::$invalidNumbers);
     }
}

请注意,如果添加

| E_STRICT

到php.ini中的error_reporting,你会看到如下消息:

  

严格的标准:非静态方法stat :: isValid()不应该静态调用,假设$ this来自不兼容的上下文...

答案 2 :(得分:2)

正确声明static方法

替换

 function isValid($number) {

public static function isValid($number) {   
         ^--- here