Nombre de constante dinámica en PHP

80

Estoy tratando de crear un nombre constante de forma dinámica y luego obtener el valor.

define( CONSTANT_1 , "Some value" ) ;

// try to use it dynamically ...
$constant_number = 1 ;
$constant_name = ("CONSTANT_" . $constant_number) ;

// try to assign the constant value to a variable...
$constant_value = $constant_name;

Pero encuentro que $ valor constante todavía contiene el NOMBRE de la constante, y no el VALOR.

También probé el segundo nivel de indirección, $$constant_namepero eso lo convertiría en una variable, no en una constante.

¿Alguien puede arrojar algo de luz sobre esto?

vikmalhotra
fuente

Respuestas:

72

Y para demostrar que esto también funciona con constantes de clase:

class Joshua {
    const SAY_HELLO = "Hello, World";
}

$command = "HELLO";
echo constant("Joshua::SAY_$command");
uɥƃnɐʌuop
fuente
12
Vale la pena señalar que es posible que deba especificar el nombre de clase totalmente calificado (espacio de nombres) si la constante está en una clase que no está en el espacio de nombres actual, independientemente de si ha agregado un "uso" para la clase en su archivo.
torcido
1
Esta respuesta es excelente debido a un buen ejemplo. Eso es exactamente lo que estaba buscando :) ¡Gracias!
ElChupacabra
6
@lopsided La ::classconstante se puede usar para recuperar el espacio de nombres completo, por ejemplo:constant(YourClass::class . '::CONSTANT_' . $yourVariable);
Willem-Aart
1
Tenga en cuenta que la ::classpalabra clave está disponible desde php 5.5
T30
9

Para usar nombres de constantes dinámicas en su clase, puede usar la función de reflexión (desde php5):

$thisClass = new ReflectionClass(__CLASS__);
$thisClass->getConstant($constName);

Por ejemplo: si desea filtrar solo constantes específicas (SORT_ *) en la clase

class MyClass 
{
    const SORT_RELEVANCE = 1;
    const SORT_STARTDATE = 2;

    const DISTANCE_DEFAULT = 20;

    public static function getAvailableSortDirections()
    {
        $thisClass = new ReflectionClass(__CLASS__);
        $classConstants = array_keys($thisClass->getConstants());

        $sortDirections = [];
        foreach ($classConstants as $constName) {
            if (0 === strpos($constName, 'SORT_')) {
                $sortDirections[] =  $thisClass->getConstant($constName);
            }
        }

        return $sortDirections;
    }
}

var_dump(MyClass::getAvailableSortDirections());

resultado:

array (size=2)
  0 => int 1
  1 => int 2
Friso
fuente