Tac*_*tex 15 php const class constants
我希望能够做到这样的事情:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但我不能从这样的表达式创建一个类常量:
该值必须是常量表达式,而不是(例如)变量,属性,数学运算的结果或函数调用.
所以我的问题是:这种PHP限制的最佳解决方法是什么?我知道以下变通方法,但还有其他更好的方法吗?
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个,因为价值$RADIUS_TO_CIRCUMFERENCE可以改变,所以它不是真正的"常数".
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是更好的,因为该值是真正恒定的,但缺点是RAD_TO_CIRCUM已经全局定义.
一个题外话
我不明白这是如何工作的.(编辑:我已经测试了它,它确实有效.)根据PHP语法手册:
该
const功能键可以创建一个编译时间常数,所以编译器将取代它的价值不断的所有使用.相反,define创建一个运行时常量,直到运行时才设置.这就是为什么define可以为常量赋予表达值,而const需要在编译时已知的常数值.
该手册确认 "使用const关键字定义的常量......在编译时定义".
在3年前的这个错误报告中,PHP团队的一名成员写道:
对于类常量,我们在编译时需要一个常量值,并且不能计算表达式.
define()是一个常规函数,在运行时进行评估,因此可以包含任何形式的任何值.
但在上面的例子中,RAD_TO_CIRCUM编译时不知道值.那么编译器的价值是RADIUS_TO_CIRCUMFERENCE什么?
我猜测编译器会为其值创建某种占位符RADIUS_TO_CIRCUMFERENCE,并且在运行时,该占位符将替换为值RAD_TO_CIRCUM.这个占位符可能是一种资源吗?如果是这样,也许应该避免这种技术?手册说:"可以将常量定义为资源,但应该避免,因为它可能会导致意外的结果."
class Circle {
...
private static function RADIUS_TO_CIRCUMFERENCE() {
return M_PI * 2;
}
public function getCircumference() {
return $this->radius * $this->RADIUS_TO_CIRCUMFERENCE();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我最喜欢的解决方法,我知道.该值是常量,不会影响全局空间.
还有其他解决方法甚至更好吗?
kei*_*sar 15
从PHP 5.6开始,您可以在PHP常量中使用数学表达式,这样就可以了:
const RADIUS_TO_CIRCUMFERENCE = M_PI * 2;
Run Code Online (Sandbox Code Playgroud)
我遇到了这个线程,因为我的环境配置不正确(偶然设置为PHP 5.4),所以不要忘记检查你的PHP版本.