693 votos

PHP y Enumeraciones

Sé que PHP no tiene nativa de las Enumeraciones. Pero ya me he acostumbrado a ellos desde el mundo de Java. Me encantaría utilizar enumeraciones como una forma de dar a los valores predefinidos que IDEs' la finalización automática de la cuenta, podía entender.

Las constantes de hacer el truco, pero no el espacio de nombres de colisión problema y (o porque) están global. Las matrices no tienen el problema de espacio de nombres, pero son demasiado vagas, que puede ser sobrescrito en tiempo de ejecución y los IDEs rara vez (nunca?) saber cómo autocompletar sus claves.

Hay soluciones/soluciones que utiliza habitualmente? ¿Alguien recuerda si el PHP chicos han tenido pensamientos o decisiones en torno a las enumeraciones?

974voto

Brian Cline Puntos 8904

Dependiendo del caso de uso, que normalmente debería usar algo simple como el siguiente:

abstract class DaysOfWeek
{
    const Sunday = 0;
    const Monday = 1;
    // etc.
}

$today = DaysOfWeek::Sunday;

(Edición en 2013-12-12)

Sin embargo, otros casos de uso pueden requerir más de la validación de constantes y valores. Basado en los comentarios a continuación sobre la reflexión, y algunas otras notas, he aquí una ampliación de ejemplo que puede servir mejor a una gama mucho más amplia de los casos:

abstract class BasicEnum {
    private static $constCache = NULL;

    private static function getConstants() {
        if (self::$constCache === NULL) {
            $reflect = new ReflectionClass(get_called_class());
            self::$constCache = $reflect->getConstants();
        }

        return self::$constCache;
    }

    public static function isValidName($name, $strict = false) {
        $constants = self::getConstants();

        if ($strict) {
            return array_key_exists($name, $constants);
        }

        $keys = array_map('strtolower', array_keys($constants));
        return in_array(strtolower($name), $keys);
    }

    public static function isValidValue($value) {
        $values = array_values(self::getConstants());
        return in_array($value, $values, $strict = true);
    }
}

abstract class DaysOfWeek extends BasicEnum {
    const Sunday = 0;
    const Monday = 1;
    const Tuesday = 2;
    const Wednesday = 3;
    const Thursday = 4;
    const Friday = 5;
    const Saturday = 6;
}

Mediante la creación de una simple enumeración de la clase que se extiende BasicEnum, ahora tiene la capacidad para utilizar métodos así de simple validación de entrada:

DaysOfWeek::isValidName('Humpday');                  // false
DaysOfWeek::isValidName('Monday');                   // true
DaysOfWeek::isValidName('monday');                   // true
DaysOfWeek::isValidName('monday', $strict = true);   // false
DaysOfWeek::isValidName(0);                          // false

DaysOfWeek::isValidValue(0);                         // true
DaysOfWeek::isValidValue(5);                         // true
DaysOfWeek::isValidValue(7);                         // false
DaysOfWeek::isValidValue('Friday');                  // false

Como una nota del lado, en cualquier momento que yo uso la reflexión, al menos, una vez en una estática/const clase donde los datos no van a cambiar (como en una enumeración), yo caché de los resultados de esas reflexión llamadas, desde el uso de nuevas reflejo de los objetos cada vez que eventualmente tendrá un notable impacto en el rendimiento.

Ahora que la mayoría de la gente , finalmente, actualizado al menos a la 5.3, y SplEnum está disponible, que es sin duda una opción viable, siempre y cuando no te importa el tradicionalmente poco intuitivo noción de real enum casos a lo largo de su código base. En el ejemplo de arriba, BasicEnum y DaysOfWeek no puede ser instanciado en absoluto, ni deben.

120voto

markus Puntos 22871

Hay una extensión nativa, también. El SplEnum

SplEnum da la capacidad de emular y crear la enumeración de los objetos de forma nativa en PHP.

http://www.php.net/manual/class.splenum.php

26voto

Peter Bailey Puntos 62125

¿Qué acerca de las constantes de clase?

<?php

class YourClass
{
    const SOME_CONSTANT = 1;

    public function echoConstant()
    {
        echo self::SOME_CONSTANT;
    }
}

echo YourClass::SOME_CONSTANT;

$c = new YourClass;
$c->echoConstant();

20voto

Andi T Puntos 464

Yo uso interface en lugar de class:

interface DaysOfWeek
{
    const Sunday = 0;
    const Monday = 1;
    // etc.
}

var $today = DaysOfWeek::Sunday;

16voto

andy.gurin Puntos 1516

He utilizado las clases con constantes:

class Enum {
    const NAME       = 'aaaa';
    const SOME_VALUE = 'bbbb';
}

print Enum::NAME;

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: