【发布时间】:2010-12-25 04:59:23
【问题描述】:
假设你在一个类中定义了一个常量:
class Foo {
const ERR_SOME_CONST = 6001;
function bar() {
$x = 6001;
// need to get 'ERR_SOME_CONST'
}
}
PHP 可以吗?
【问题讨论】:
假设你在一个类中定义了一个常量:
class Foo {
const ERR_SOME_CONST = 6001;
function bar() {
$x = 6001;
// need to get 'ERR_SOME_CONST'
}
}
PHP 可以吗?
【问题讨论】:
class OrderStatus
{
public const PENDING = 1;
public const PROCESSED = 2;
public static function getStatusCode($value)
{
$class = new ReflectionClass(__CLASS__);
$constants = array_flip($class->getConstants());
return $constants[$value] ?? null;
}
// OrderStatus::getStatusCode(1); // 'PENDING'
}
【讨论】:
所有常量都可以使用这个函数赋值给一个数组。
$const = get_defined_constants();
然后使用以下函数可以打印数组结构
echo "<pre>";
print_r($const);
你可以在这里看到更多的解释www.sugunan.com
【讨论】:
好的,好的,我知道一切都已经涵盖了:) 但是 Jan 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());
});
【讨论】:
所有其他答案都涵盖了要点。但是,如果你喜欢疯狂的一个班轮,那么:
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);
}
【讨论】:
这是我为实现它所做的。灵感来自 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];
}
}
【讨论】:
警告:这样你不应该编程......(如果你不确定你在做什么:))
我写了 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;
}
}
【讨论】:
我知道这是一个老问题,但我仍然觉得我有一些有用的意见。我使用我所有的枚举都扩展的抽象类来实现这一点。抽象类包含一个通用的 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>";
}
【讨论】:
您可以通过reflection 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:你介意说出你为什么需要这个,因为它看起来很不寻常......
【讨论】:
curl_multi_strerror 不可用的情况下也需要它来获得 CURLE_* 持续支持
带反射:
$class = new ReflectionClass("Foo");
$constants = $class->getConstants();
$constants 是一个数组,其中包含 Foo 类中定义的所有常量的名称和值。
【讨论】: