web-dev-qa-db-fra.com

Comment obtenir le nom de la constante?

En supposant que vous ayez une constante définie dans une classe:

class Foo {
    const ERR_SOME_CONST = 6001;

    function bar() {
        $x = 6001;
        // need to get 'ERR_SOME_CONST'
    }
}

Est-ce possible avec PHP?

49
Deniss Kozlovs

Vous pouvez les obtenir avec API de réflexion

Je suppose que vous souhaitez obtenir le nom de la constante en fonction de la valeur de votre variable (valeur de variable == valeur de constante). Obtenez toutes les constantes définies dans la classe, parcourez-les et comparez les valeurs de ces constantes avec la valeur de votre variable. Notez qu'avec cette approche, vous pouvez obtenir une autre constante que celle que vous souhaitez, s'il y a deux constantes avec la même valeur.

exemple:

class Foo {
    const ERR_SOME_CONST = 6001;
    const ERR_SOME_OTHER_CONST = 5001;

    function bar() {
        $x = 6001;
        $fooClass = new ReflectionClass ( 'Foo' );
        $constants = $fooClass->getConstants();

        $constName = null;
        foreach ( $constants as $name => $value )
        {
            if ( $value == $x )
            {
                $constName = $name;
                break;
            }
        }

        echo $constName;
    }
}

ps: ça vous dérange de dire pourquoi vous en avez besoin, car cela semble très inhabituel ...

57
Jan Hančič

Voici ce que j'ai fait pour y parvenir. Inspiré par Jan Hancic.

class ErrorCode
{
    const COMMENT_NEWCOMMENT_DISABLED = -4;
    const COMMENT_TIMEBETWEENPOST_ERROR = -3;
    /**
     * Get error message of a value. It's actually the constant's name
     * @param integer $value
     * 
     * @return string
     */
    public static function getErrorMessage($value)
    {
        $class = new ReflectionClass(__CLASS__);
        $constants = array_flip($class->getConstants());

        return $constants[$value];
    }
}
26
deathemperor

Avec réflexion:

$class = new ReflectionClass("Foo");
$constants = $class->getConstants();

$constants est un tableau qui contient tous les noms et valeurs des constantes définies dans la classe Foo.

13
Davide Gualano

Je sais que c'est une vieille question et tout, mais je sens toujours que j'ai une contribution utile. J'ai implémenté cela en utilisant une classe abstraite que toutes mes énumérations étendent. La classe abstraite contient une méthode générique toString ();

abstract class BaseEnum{
    private final function __construct(){ }

    public static function toString($val){
        $tmp = new ReflectionClass(get_called_class());
        $a = $tmp->getConstants();
        $b = array_flip($a);

        return ucfirst(strtolower($b[$val]));
    }
}

//actual enum
final class UserType extends BaseEnum {
    const ADMIN = 10;
    const USER = 5;
    const VIEWER = 0;
}

De cette façon, vous pouvez obtenir une chaîne lisible par l'homme à utiliser en sortie, sur chaque énumération qui étend l'énumération de base. De plus, votre implémentation de l'énum, ​​étant final, ne peut pas être étendue et parce que le constructeur dans BaseEnum est private, elle ne peut jamais être instanciée.

Ainsi, par exemple, si vous affichez une liste de tous les noms d'utilisateur avec leurs types, vous pouvez faire quelque chose comme

foreach($users as $user){
    echo "<li>{$user->name}, ".UserType::toString($user->usertype)."</li>";
}
10
rael_kid

Toutes les autres réponses couvrent les points essentiels. Mais, si vous êtes un truc de fou, alors:

function getConstantName($class, $value)
{
    return array_flip((new \ReflectionClass($class))->getConstants())[$value];
}

Si vous devez gérer le cas où la valeur pourrait ne pas être réellement l'une des constantes, vous pouvez renoncer à une ligne supplémentaire:

function getConstantName($class, $value)
{
    $map = array_flip((new \ReflectionClass($class))->getConstants());
    return (array_key_exists($value, $map) ? $map[$value] : null);
}
8
bishop

Toutes les constantes peuvent être affectées à un tableau à l'aide de cette fonction.

$const = get_defined_constants();

puis en utilisant la fonction suivante, vous pouvez imprimer la structure du tableau

echo "&lt;pre&gt;";

print_r($const);

et vous pouvez voir plus d'explications ici www.sugunan.com

4
Kevin

Avertissement: De cette façon, vous ne devez PAS programmer ... (si vous n'êtes pas sûr de ce que vous faites :))

J'ai écrit 1 ligne indiquant les constantes d'échos et leurs valeurs numériques en choisissant CATEGORY_

voici donc la liste des CATEGORY_ ERR_

foreach(get_defined_constants() as $key => $value) if(strlen($key)>5) if(substr($key, 0,5)=="ERR_") echo"<br>Found an php ERR_ constant! : ".$key."=>".$value;

Et si vous voulez juste celui que vous recherchez par numéro => j'ai créé la fonction 1row:

//input parameters: CATEGORYNAME_ , #constantNumber
function getConstantName($category,$constantNumber){foreach(get_defined_constants() as $key => $value) if(strlen($key)>strlen($category)) if(substr($key, 0,strlen($category))==$category) if($value==$constantNumber) return $key; return "No constant found.";}

Ainsi, par exemple, une constante d'information avec le nombre 64:

echo "NameOfConstant: ".getConstantName("INFO_",64);

produira quelque chose comme: NameOfConstant: INFO_LICENSE

3
jave

OK, OK, je sais que tout est déjà couvert :) Mais Jan Hančič a demandé un cas d'utilisation, je vais donc partager le mien. A part: tout le monde semble utiliser array_flip (). Pourquoi pas array_search ()?

J'en avais besoin dans une classe qui étend\Exception et est la classe de base d'un petit ensemble de mes exceptions concrètes. Chacune de ces classes d'exceptions concrètes couvre un vaste domaine d'exceptions et a défini plusieurs causes d'exceptions précises. Raison? Je ne veux pas avoir une horde d'exceptions à maintenir et à retenir. En outre, il existe un ensemble de gestionnaires d'exceptions qui transfère les entrailles des exceptions dans le fichier journal - et c'est ici que j'ai besoin d'obtenir le nom constant comme essayant de déchiffrer la cause de l'exception de l'état dans assez douloureux.

Exemples de mes scripts CLI:

class AbstractException extends Exception {
    public function getName() {
        return array_search($this->getCode(), (new ReflectionClass($this))->getConstants());
    }
}

class SyntaxException extends AbstractException {
    const BAD_SYNTAX = 90;
    const REQUIRED_PARAM = 91;
    const REQUIRED_VALUE = 92;
    const VALUE_TYPE = 93;
    const VALUE_OUT_OF_BOUNDS = 94;

    public function __construct ($message = "", $code = self::BAD_SYNTAX, Exception $previous = NULL) {
        $script = basename($GLOBALS['argv'][0]);

        echo "Invalid syntax: $message \nSee: `$script --help` for more information\n";
        parent::__construct($message, $code, $previous);
    }
}

// in autoload include
set_exception_handler(function(Exception $e) {
    error_log(basename($GLOBALS['argv'][0]) . ';'. date('Y-m-d H:i:s') .';'. $e->getName() .';'. $e->getMessage() .';'. $e->getFile() .';'. $e->getLine() ."\n", 3, 'error.log');
    exit ($e->getCode());
});
2
Forseti

si vous avez besoin d'obtenir la valeur constante sur une méthode de la même classe, il vous suffit d'utiliser l'auto-opérateur. Vous pouvez utiliser la réflexion si vous souhaitez utiliser les constantes sur une autre classe

class Foo {
    const ERR_SOME_CONST = 6001;

    function bar() {
        self::ERR_SOME_CONST;
    }
}
1
Andrés Sendra