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

Ben*_*Ben 108 php class-constants

我希望能够做到这样的事情:

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

$thing = 'Something';
$id = ThingIDs::$thing;
Run Code Online (Sandbox Code Playgroud)

这不起作用.做一些等效的直接方式吗?请注意,我坚持上课; 它在图书馆我无法重写.我正在编写在命令行上接受参数的代码,我真的希望它采用符号名而不是id号.

Dan*_*mon 174

$id = constant("ThingIDs::$thing");

http://php.net/manual/en/function.constant.php

  • 旁注:如果你想首先检查常量是否已定义,则为 `define("ThingIDs::$thing");` (4认同)
  • @DavidBaucum为什么你想要过度复杂呢?请求非常简单,不涉及外部,用户可操作的输入.除此之外,你正在调用另一个函数,因为,我想,你不喜欢字符串与分隔符连接? (4认同)
  • 或$ id =常量("self :: $ thing"); (3认同)
  • 与此类似,```$ id = constant(sprintf('%s ::%s',ThingIDs :: class,$ thing));``` (2认同)
  • 根据您的使用情况,我的解决方案不那么复杂.特别是如果你正在使用PSR-4自动加载,那么你的代码中可能会很难看到FQDN到处拼写.通过在文件顶部使用```use```然后使用```:: class```方法神奇地获取FQDN提高了可读性. (2认同)

Phi*_*hil 25

使用反射

$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
Run Code Online (Sandbox Code Playgroud)

  • 反思确实提供了很多关于类,方法等的洞察力,似乎很多人都害怕采取这一步来理解它们.很好的答案. (3认同)
  • @mikemackintosh 我已采取措施来理解它们,但在性能影响与已接受的答案方面没有看到太多。这是我有兴趣了解的。实例化一个新类似乎比简单地静态调用一个常量会带来更大的性能损失。你对此有何看法? (2认同)

Jor*_*oon 12

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

echo constant('My\Application\ThingClass::ThingConstant'); 
Run Code Online (Sandbox Code Playgroud)


Glu*_*exo 5

辅助功能

\n\n

您可以使用这样的函数:

\n\n
function class_constant($class, $constant)\n{\n    if ( ! is_string($class)) {\n        $class = get_class($class);\n    }\n\n    return constant($class . '::' . $constant);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它需要两个参数:

\n\n
    \n
  • 类名或对象实例
  • \n
  • 类常量名称
  • \n
\n\n

如果传递一个对象实例,则会推断其类名。如果您使用 PHP\xc2\xa07,则可以使用::class传递适当的类名而无需考虑命名空间。

\n\n

例子

\n\n
class MyClass\n{\n    const MY_CONSTANT = 'value';\n}\n\nclass_constant('MyClass', 'MY_CONSTANT'); # 'value'\nclass_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP\xc2\xa07 only)\n\n$myInstance = new MyClass;\nclass_constant($myInstance, 'MY_CONSTANT'); # 'value'\n
Run Code Online (Sandbox Code Playgroud)\n