获取PHP中动态选择的类常量的值

获取PHP中动态选择的类常量的值,php,class-constants,Php,Class Constants,我希望能够做到以下几点: class ThingIDs { const Something = 1; const AnotherThing = 2; } $thing = 'Something'; $id = ThingIDs::$thing; function class_constant($class, $constant) { if ( ! is_string($class)) { $class = get_class($class);

我希望能够做到以下几点:

class ThingIDs
{
    const Something = 1;
    const AnotherThing = 2;
}

$thing = 'Something';
$id = ThingIDs::$thing;
function class_constant($class, $constant)
{
    if ( ! is_string($class)) {
        $class = get_class($class);
    }

    return constant($class . '::' . $constant);
}
这不管用。有没有一种简单的方法来做一些等效的事情?请注意,我被困在课堂上;它在图书馆里,我无法重写。我正在编写在命令行上接受参数的代码,我真的希望它接受符号名而不是id号。

使用反射

$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
使用反射

$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
$id=constant(“thingid::$thing”)

$id=constant(“thingid::$thing”)


如果使用名称空间,则应将名称空间包含在类中

echo constant('My\Application\ThingClass::ThingConstant'); 

如果您使用的是名称空间,那么应该在类中包含名称空间

echo constant('My\Application\ThingClass::ThingConstant'); 

如果有对类本身的引用,则可以执行以下操作:

if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
   // class constant is defined
}

如果有对类本身的引用,则可以执行以下操作:

if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
   // class constant is defined
}
辅助函数 您可以使用如下函数:

class ThingIDs
{
    const Something = 1;
    const AnotherThing = 2;
}

$thing = 'Something';
$id = ThingIDs::$thing;
function class_constant($class, $constant)
{
    if ( ! is_string($class)) {
        $class = get_class($class);
    }

    return constant($class . '::' . $constant);
}
它包含两个参数:

  • 类名或对象实例
  • 类常量名
如果传递了对象实例,则会推断其类名。如果使用PHP7,则可以使用
::class
传递适当的类名,而不必考虑名称空间

例子 辅助函数 您可以使用如下函数:

class ThingIDs
{
    const Something = 1;
    const AnotherThing = 2;
}

$thing = 'Something';
$id = ThingIDs::$thing;
function class_constant($class, $constant)
{
    if ( ! is_string($class)) {
        $class = get_class($class);
    }

    return constant($class . '::' . $constant);
}
它包含两个参数:

  • 类名或对象实例
  • 类常量名
如果传递了对象实例,则会推断其类名。如果使用PHP7,则可以使用
::class
传递适当的类名,而不必考虑名称空间

例子
我的问题与这个问题相似。如果您有对象,但没有类名,则可以使用:

$class_name = get_class($class_object);
$class_const = 'My_Constant';

$constant_value = constant($class_name.'::'.$class_const);

我的问题与这个问题相似。如果您有对象,但没有类名,则可以使用:

$class_name = get_class($class_object);
$class_const = 'My_Constant';

$constant_value = constant($class_name.'::'.$class_const);

我知道我有点晚了,但我希望这能有所帮助

根据的答案,我创建了一个可以扩展的默认枚举器类

class DefaultEnum
{
    static public function getConstantText(string $constant)
    {
        try {
            // Get child class name that called this method
            $child_class = get_called_class();

            $reflection = new ReflectionClass($child_class);
            $const = $reflection->getConstant($constant);

            return $const;
        } catch (\ReflectionException $e) {
            // ...
        }
    }
}

class CustomEnum extends DefaultEnum
{
    const something = 'abcd';
    const something2 = 'ABCD';
}
您可以这样调用此方法

CustomEnum::getConstantText('something');
它将返回
'abcd'

函数是一个返回调用此方法的类名的函数,它专门用于静态方法


在这种情况下,
$child\u class
值将是
CustomEnum::class
。ReflectionClass接受字符串和对象作为参数。

我知道我有点晚了,但我希望这能有所帮助

根据的答案,我创建了一个可以扩展的默认枚举器类

class DefaultEnum
{
    static public function getConstantText(string $constant)
    {
        try {
            // Get child class name that called this method
            $child_class = get_called_class();

            $reflection = new ReflectionClass($child_class);
            $const = $reflection->getConstant($constant);

            return $const;
        } catch (\ReflectionException $e) {
            // ...
        }
    }
}

class CustomEnum extends DefaultEnum
{
    const something = 'abcd';
    const something2 = 'ABCD';
}
您可以这样调用此方法

CustomEnum::getConstantText('something');
它将返回
'abcd'

函数是一个返回调用此方法的类名的函数,它专门用于静态方法


在这种情况下,
$child\u class
值将是
CustomEnum::class
。ReflectionClass接受字符串和对象作为参数。

您可以试试
thingId::{$thing}
?已经试过了。获取一个分析错误,而不是致命的运行时错误。是否可以尝试
ThingID::{$thing}
?已尝试。给我一个解析错误,而不是致命的运行时错误。反射确实提供了很多对类、方法等的洞察,似乎很多人都不敢采取这一步骤来理解它们。回答得很好。@mikemackintosh我已经采取了一些步骤来理解它们,但是在性能影响方面与公认的答案相比还没有看到太多。这是我很想知道的。实例化一个新类似乎比静态调用常量对性能的影响更大。你对此有何看法?反思确实提供了很多关于类、方法等方面的见解,而且似乎很多人都不敢迈出这一步去理解它们。回答得很好。@mikemackintosh我已经采取了一些步骤来理解它们,但是在性能影响方面与公认的答案相比还没有看到太多。这是我很想知道的。实例化一个新类似乎比静态调用常量对性能的影响更大。您对此有何想法?旁注:如果您想首先检查常量是否已定义,它是
已定义的(“thingid::$thing”)
或$id=常量(“self::$thing”);与此类似,
$id=constant(sprintf(“%s::%s',thingid::class,$thing))@DavidBaucum你为什么要把事情复杂化?请求非常简单,不涉及外部用户可操作的输入。除此之外,您调用另一个函数是因为,我想,您不喜欢字符串与分隔符连接?根据您的使用情况,我的解决方案不太复杂。特别是,如果您使用的是PSR-4自动加载,那么在代码中到处拼写FQDN可能会很难看。通过在文件顶部使用
use
,然后使用
::class
方法神奇地获取FQDN,可以提高可读性。旁注:如果您想首先检查常量是否已定义,那么它已定义(“thingID::$thing”)
或$id=常量(“self::$thing”);与此类似,
$id=constant(sprintf(“%s::%s',thingid::class,$thing))@DavidBaucum你为什么要把事情复杂化?请求非常简单,不涉及外部用户可操作的输入。除此之外,您调用另一个函数是因为,我想,您不喜欢字符串与分隔符连接?根据您的使用情况,我的解决方案不太复杂。特别是,如果您使用的是PSR-4自动加载,那么在代码中到处拼写FQDN可能会很难看。通过在文件顶部使用
use
,然后使用
::class
方法神奇地获取FQDN,可以提高可读性。