Как получить имя константы?
если у вас есть константа, определенная в класс:
class Foo {
const ERR_SOME_CONST = 6001;
function bar() {
$x = 6001;
// need to get 'ERR_SOME_CONST'
}
}
возможно ли это с PHP?
9 ответов
вы можете получить их с отражение 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: не могли бы вы рассказать, зачем вам это нужно, так как это кажется очень необычным ...
вот что я сделал, чтобы достичь этого. Вдохновленный Яном Ханчичем.
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];
}
}
С Отражением:
$class = new ReflectionClass("Foo");
$constants = $class->getConstants();
$constants
- это массив, который содержит все имена и значения констант, определенных в классе Foo.
Я знаю, что это старый вопрос и все такое, но я все еще чувствую, что у меня есть полезный вклад. Я реализовал это, используя абстрактный класс, который расширяют все мои перечисления. Абстрактный класс содержит универсальный метод 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
is private
это невозможно создать экземпляр.
например, если вы покажете список всех имен пользователей с их типами, вы можете сделать что-то вроде
foreach($users as $user){
echo "<li>{$user->name}, ".UserType::toString($user->usertype)."</li>";
}
все остальные ответы охватывают основные моменты. Но, если crazy one liners-это ваша вещь, то:
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);
}
предупреждение: таким образом, вы не должны программировать... (если вы не уверены, что делаете :) )
Я написал 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
Если вам нужно получить значение константы по методу того же класса, вам просто нужно использовать оператор self. Вы можете использовать отражение, если хотите использовать константы в другом классе
class Foo {
const ERR_SOME_CONST = 6001;
function bar() {
self::ERR_SOME_CONST;
}
}
ОК, ОК, я знаю, что все уже покрыто :) Но Ян Hančič просил дело использовать, поэтому я поделюсь своим. В стороне: все, кажется, используют 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());
});
вся константа может быть назначена массиву с помощью этой функции.
$const = get_defined_constants();
затем, используя следующую функцию, вы можете распечатать структуру массива
echo "<pre>";
print_r($const);
и вы можете увидеть больше объяснений здесь www.sugunan.com