考虑下面的示例。类A具有private const SOMETHING
,但类b具有protected const SOMETHING
。
class a {
private const SOMETHING = 'This is a!';
public static function outputSomething() {
return static::SOMETHING ?? self::SOMETHING;
}
}
class b extends a {
protected const SOMETHING = 'This is b!';
}
echo (new b())::outputSomething();
输出:
This is b!
但是现在,如果我注释掉类b中
SOMETHING
的定义,则会引发错误:class a {
private const SOMETHING = 'This is a!';
public static function outputSomething() {
return static::SOMETHING ?? self::SOMETHING;
}
}
class b extends a {
//protected const SOMETHING = 'This is b!';
}
echo (new b())::outputSomething();
输出:
Fatal error: Uncaught Error: Cannot access private const b::SOMETHING in {file}.php:7
但是,在a类中将可见性从
private const SOMETHING
更改为protected const SOMETHING
可以解决此问题。class a {
protected const SOMETHING = 'This is a!';
public static function outputSomething() {
return static::SOMETHING ?? self::SOMETHING;
}
}
class b extends a {
//protected const SOMETHING = 'This is b!';
}
echo (new b())::outputSomething();
现在输出是预期的:
This is a!
我不明白为什么php在应用null合并运算符之前评估b::SOMETHING,根据the documentation:
由于未设置b::SOMETHING,为什么第一个示例无法正常工作,并且基类中的常量需要一致的可见性?
最佳答案
感谢@Devon和@Dormilich的回复。
TL; DR:您不能将null合并运算符(??
)与常量一起使用。您必须改为使用defined()
。
根据the documentation for the null coalescing operator (??):
意思是$x ?? $y
是isset($x) ? $x : $y
的简写。这就是问题所在,因为documentation for isset明确指出:
那就是抛出致命的php错误的原因,我在问题中对此进行了描述。相反,一种解决方案是取消空合并运算符,然后将其替换为defined()
:
class a {
private const SOMETHING = 'This is a!';
public static function outputSomething() {
return defined('static::SOMETHING') ? static::SOMETHING : self::SOMETHING;
}
}
class b extends a {
//protected const SOMETHING = 'This is b!';
}
echo (new b())::outputSomething();
第二种解决方案是首先更改代码的工作方式。正如@Devon正确指出的那样,
private
的a::SOMETHING
可见性阻止了b类看到它,因此未定义b::SOMETHING
。但是,当a::SOMETHING
的可见性更改为protected
时,类b可以看到它,并且b::SOMETHING
引用它。这段代码根本不需要null合并运算符,并且可以只使用static::SOMETHING
而无需任何条件:class a {
protected const SOMETHING = 'This is a!';
public static function outputSomething() {
return static::SOMETHING;
}
}
class b extends a {
//protected const SOMETHING = 'This is b!';
}
echo (new b())::outputSomething();
关于php - 为什么PHP的null合并运算符(??)不能在具有不同可见性的类常量上工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50971530/