¿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?
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".
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;
}
}
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".
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?