Как получить имя константы?

Предполагая, что у вас есть константа, определенная в классе:

class Foo {
    const ERR_SOME_CONST = 6001;

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

Возможно ли это с PHP?

Ответ 1

Вы можете получить их с помощью API отражения

Я предполагаю, что вы хотите получить имя константы на основе значения вашей переменной (значение переменной == значение константы). Получите все константы, определенные в классе, обведите их над ними и сравните значения этих констант со значением переменной. Обратите внимание, что при таком подходе вы можете получить некоторую другую константу, которая вам нужна, если есть две константы с одинаковым значением.

Пример:

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: вы не возражаете сказать, зачем вам это нужно, поскольку это кажется очень необычным...

Ответ 2

Вот что я сделал для этого. Вдохновленный Ян Хэнсик.

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

        return $constants[$value];
    }
}

Ответ 3

С отражением:

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

$constants - это массив, который содержит все имена и значения констант, определенных в классе Foo.

Ответ 4

Я знаю, что это старый вопрос и все, но я все еще чувствую, что у меня есть полезный вклад. Я реализовал это, используя абстрактный класс, который распространяется на все мои перечисления. Абстрактный класс содержит общий метод 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;
}

Таким образом, вы можете получить удобочитаемую строку для использования в выводе, на каждом перечислении, которое расширяет базовое перечисление. Кроме того, ваша реализация перечисления, будучи final, не может быть расширена и потому что конструктор в BaseEnum равен private, он никогда не может быть создан.

Так, например, если вы показываете список всех имен пользователей с их типами, вы можете сделать что-то вроде

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

Ответ 5

Все остальные ответы охватывают основные моменты. Но, если сумасшедший один лайнер - это ваша вещь, то:

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

Если вам нужно обработать случай, когда значение может фактически не быть одной из констант, вы можете отказаться от дополнительной строки:

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

Ответ 6

Предупреждение: таким образом вы НЕ должны программировать... (если вы не уверены, что вы делаете:))

Я написал 1 строку, константы эхо и их числовые значения по вашему выбору CATEGORY _

так вот список 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;

И если вам нужен только тот, который вы ищете по номеру = > , я создал функцию 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.";}

Итак, например, некоторая информационная константа с номером 64:

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

выведет что-то вроде: NameOfConstant: INFO_LICENSE

Ответ 7

если вам нужно получить постоянное значение для метода того же класса, вам просто нужно использовать оператор self. Вы можете использовать отражение, если хотите использовать константы в другом классе

class Foo {
    const ERR_SOME_CONST = 6001;

    function bar() {
        self::ERR_SOME_CONST;
    }
}

Ответ 8

ОК, хорошо, я знаю, что все уже покрыто:) Но Ян Ханчич попросил использовать прецедент, поэтому я поделюсь с вами. Кроме того, все, похоже, используют array_flip(). Почему не array_search()?

Мне нужно было это в классе, который расширяет \Exception и является базовым классом небольшого набора моих конкретных исключений. Каждый из этих конкретных классов исключений охватывает обширный домен исключения и определяет несколько точных причин исключения. Причина? Я не хочу иметь орды исключений для поддержания и запоминания. Кроме того, существует набор обработчиков исключений, который выгружает исключение в файл журнала - и здесь мне нужно получить постоянное имя, пытаясь дешифровать причину исключения из состояния в довольно болезненном.

Примеры из моих сценариев 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());
});

Ответ 9

Все константы могут быть назначены массиву с помощью этой функции.

$const = get_defined_constants();

затем используя следующую функцию, вы можете напечатать структуру массива

echo "&lt;pre&gt;";

print_r($const);

и вы можете увидеть больше объяснений здесь www.sugunan.com