从表达式创建PHP类常量的最佳解决方法? [英] Best workaround to create a PHP class constant from an expression?

查看:100
本文介绍了从表达式创建PHP类常量的最佳解决方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够做这样的事情:

I'd like to be able to do something like this:

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;
    }

}

但是我无法从表达式创建类常量像这样:

But I can't create a class constant from an expression like that:

该值必须是一个常量表达式,而不是(例如)变量,属性,数学运算结果或函数调用.

The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call.


所以我的问题是:针对此PHP限制的最佳解决方法是什么?我知道以下解决方法,但是还有其他更好的方法吗?


So my question is: What's the best workaround for this limitation of PHP? I'm aware of the following workarounds, but are there any others which are better?

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的值可以更改,因此它并不是真正的常数".

I don't like this, because the value of $RADIUS_TO_CIRCUMFERENCE can be changed, so it's not really a "constant".

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已全局定义.

This is better, since the value is truly constant, but the drawback is that RAD_TO_CIRCUM has been globally defined.

题外话

我不知道这是怎么工作的. (我已经对其进行了测试,并且可以正常工作.)根据 PHP语法手册:

I don't understand how this can work. ( I've tested it, and it does work.) According to the Handbook of PHP Syntax:

const修饰符将创建一个编译时常量,因此编译器将使用其值替换该常量的所有用法.相反,define创建一个运行时常量,直到运行时才设置.这就是为什么define常量可以分配表达式值,而const则需要在编译时已知的常量值的原因.

The const modifier creates a compile-time constant and so the compiler will replace all usage of the constant with its value. In contrast, define creates a run-time constant which is not set until run-time. This is the reason why define constants may be assigned with expressional values, whereas const requires constant values which are known at compile-time.

手册确认使用const定义的常量关键字...是在编译时定义的."

The manual confirms that "constants defined using the const keyword ... are defined at compile-time".

3年前的此错误报告团队写道:

对于类常量,我们在编译时需要一个常量值,并且不能对表达式求值. define()是常规函数,在运行时求值,因此可以包含任何形式的任何值.

For the class constant we need a constant value at compile time and can't evaluate expressions. define() is a regular function, evaluated at run time and can therefore contain any value of any form.

但是在上面的示例中,RAD_TO_CIRCUM的值在编译时未知.那么,编译器将RADIUS_TO_CIRCUMFERENCE的值放在什么位置?

But in my example above, the value of RAD_TO_CIRCUM is not known at compile-time. So what is the compiler putting for the value of RADIUS_TO_CIRCUMFERENCE?

我猜测编译器会为RADIUS_TO_CIRCUMFERENCE的值创建某种占位符,并且在运行时,该占位符将被替换为RAD_TO_CIRCUM的值.这个占位符可能是资源的一种吗?如果是这样,也许应该避免这种技术?手册:可以将常量定义为一种资源,但应避免这样做,因为它可能会导致意外的结果."

I'm guessing that the compiler creates some kind of placeholder for the value of RADIUS_TO_CIRCUMFERENCE, and at run-time, that placeholder gets replaced with the value of RAD_TO_CIRCUM. Might this placeholder be a kind of resource? If so, maybe this technique should be avoided? The manual says: "It is possible to define constants as a resource, but it should be avoided, as it can cause unexpected results."

class Circle {

    ...

    private static function RADIUS_TO_CIRCUMFERENCE() {
        return M_PI * 2;
    }

    public function getCircumference() {
        return $this->radius * $this->RADIUS_TO_CIRCUMFERENCE();
    }

}

这是我所知道的我最喜欢的解决方法.该值是常数,并且不会影响全局空间.

This is my favourite workaround that I'm aware of. The value is constant, and it doesn't affect the global space.

还有另一种更好的解决方法吗?

Is there another workaround which is even better?

推荐答案

从PHP 5.6开始,您可以使用

As of PHP 5.6, you can use math expressions in PHP constants, so this would work:

const RADIUS_TO_CIRCUMFERENCE = M_PI * 2;

我遇到此线程是因为我的环境配置不正确(偶然将其设置为PHP 5.4),所以请不要忘记检查您的PHP版本.

I encountered this thread because my environment wasn't configured properly (was set to PHP 5.4 by accident), so don't forget to check your PHP version.

这篇关于从表达式创建PHP类常量的最佳解决方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆