¿La mejor solución para crear una constante de clase PHP a partir de una expresión?

Me gustaría poder hacer algo como esto:

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

}

Pero no puedo crear unconstante de clase de una expresión como esa:

El valor debe ser una expresión constante, no (por ejemplo) una variable, una propiedad, un resultado de una operación matemática o una llamada a una función.


Entonces mi pregunta es: ¿Cuál es la mejor solución para esta limitación de PHP? Soy consciente de las siguientes soluciones, pero ¿hay otras que sean mejores?

1. Crear una propiedad
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;
    }

}

No me gusta esto, porque el valor de$RADIUS_TO_CIRCUMFERENCE se puede cambiar, por lo que no es realmente una "constante".

2. Utilicedefine()
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;
    }

}

Esto es mejor, ya que el valor es verdaderamente constante, pero el inconveniente es queRAD_TO_CIRCUM Se ha definido globalmente.

Una digresion

No entiendo cómo esto puede funcionar.(Edit: lo he probado, y funciona). De acuerdo con laManual de sintaxis de PHP:

losconst el modificador crea una constante de tiempo de compilación y, por lo tanto, el compilador reemplazará todo el uso de la constante con su valor. A diferencia de,define crea una constante de tiempo de ejecución que no se establece hasta el tiempo de ejecución. Esta es la razón porquedefine Las constantes pueden asignarse con valores expresionales, mientras queconst Requiere valores constantes que son conocidos en tiempo de compilación.

El manualconfirma que "constantes definidas usando laconst palabra clave ... se definen en tiempo de compilación ".

Eneste informe de error Desde hace 3 años, un miembro del equipo de PHP escribió:

Para la constante de clase necesitamos un valor constante en el momento de la compilación y no podemos evaluar expresiones.define() es una función regular, evaluada en tiempo de ejecución y, por lo tanto, puede contener cualquier valor de cualquier forma.

Pero en mi ejemplo anterior, el valor deRAD_TO_CIRCUM No se conoce en tiempo de compilación. Entonces, ¿qué está poniendo el compilador por el valor deRADIUS_TO_CIRCUMFERENCE?

Supongo que el compilador crea algún tipo de marcador de posición por el valor deRADIUS_TO_CIRCUMFERENCE, y en tiempo de ejecución, ese marcador de posición se reemplaza con el valor deRAD_TO_CIRCUM. ¿Podría este marcador de posición ser una especie derecurso? Si es así, tal vez debería evitarse esta técnica? El manualdice: "Es posible definir constantes como un recurso, pero debe evitarse, ya que puede causar resultados inesperados".

3. Crea un método
class Circle {

    ...

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

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

}

Esta es mi solución favorita que conozco. El valor es constante y no afecta al espacio global.

¿Hay otra solución que sea aún mejor?

Respuestas a la pregunta(4)

Su respuesta a la pregunta