从表达式创建 PHP 类常量的最佳解决方法?
我希望能够做这样的事情:
class Circle {
const RADIUS_TO_CIRCUMFERENCE = M_PI * 2; // Not allowed
private $radius;
public function __construct( $radius ) {
$this->radius = $radius;
}
...
public function getCircumference() {
return $this->radius * self::RADIUS_TO_CIRCUMFERENCE;
}
}
但是我不能从这样的表达式创建类常量:
该值必须是常量表达式,而不是(例如)变量、属性、数学运算的结果或函数调用。
所以我的问题是:PHP的这种限制的最佳解决方法是什么?我知道以下解决方法,但是还有其他更好的方法吗?
1. 创建属性
class Circle {
private static $RADIUS_TO_CIRCUMFERENCE;
private $radius;
public function __construct( $radius ) {
$this->radius = $radius;
$this->RADIUS_TO_CIRCUMFERENCE = M_PI * 2;
}
...
public function getCircumference() {
return $this->radius * $this->RADIUS_TO_CIRCUMFERENCE;
}
}
我不喜欢这样,因为的值是可以改变的,所以它并不是一个真正的“常量”。$RADIUS_TO_CIRCUMFERENCE
2. 使用define()
define( 'RAD_TO_CIRCUM', M_PI * 2 );
class Circle {
const RADIUS_TO_CIRCUMFERENCE = RAD_TO_CIRCUM;
...
public function getCircumference() {
return $this->radius * self::RADIUS_TO_CIRCUMFERENCE;
}
}
这更好,因为值确实是恒定的,但缺点是已经全局定义。RAD_TO_CIRCUM
题外话
我不明白这怎么能工作。(编辑:我已经测试过了,它确实有效。根据PHP语法手册:
修饰符创建一个编译时常量,因此编译器将用其值替换该常量的所有用法。相反,创建一个运行时常量,直到运行时才设置该常量。这就是为什么常量可以分配表达式值,而需要编译时已知的常量值的原因。
const
define
define
const
该手册确认“使用关键字定义的常量...在编译时定义”。const
在3年前的这份错误报告中,PHP团队的一名成员写道:
对于类常量,我们需要在编译时使用常量值,并且无法计算表达式。 是一个常规函数,在运行时计算,因此可以包含任何形式的任何值。
define()
但在我上面的示例中,编译时不知道 的值。那么编译器为 的值放了什么?RAD_TO_CIRCUM
RADIUS_TO_CIRCUMFERENCE
我猜编译器为 的值创建了某种占位符,并且在运行时,该占位符被替换为 的值。这个占位符可能是一种资源吗?如果是这样,也许应该避免这种技术?该手册说:“可以将常量定义为资源,但应该避免,因为它可能导致意外的结果。RADIUS_TO_CIRCUMFERENCE
RAD_TO_CIRCUM
3. 创建方法
class Circle {
...
private static function RADIUS_TO_CIRCUMFERENCE() {
return M_PI * 2;
}
public function getCircumference() {
return $this->radius * $this->RADIUS_TO_CIRCUMFERENCE();
}
}
这是我所知道的我最喜欢的解决方法。该值是常量,并且不会影响全局空间。
有没有另一种更好的解决方法?