我有一个静态函数被调用,它给出了一个奇怪的错误。以下是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
会发生此错误?
答案 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