获取PHP中动态选择的类常量的值
Posted
技术标签:
【中文标题】获取PHP中动态选择的类常量的值【英文标题】:Get value of dynamically chosen class constant in PHP 【发布时间】:2011-09-03 01:50:28 【问题描述】:我希望能够做这样的事情:
class ThingIDs
const Something = 1;
const AnotherThing = 2;
$thing = 'Something';
$id = ThingIDs::$thing;
这不起作用。有没有一种直接的方法来做等效的事情?请注意,我坚持上课;它在我无法重写的库中。我正在编写在命令行上接受参数的代码,并且我真的希望它采用符号名称而不是 id 数字。
【问题讨论】:
你能试试ThingIDs::$thing
吗?
已经试过了。给我一个解析错误,而不是一个致命的运行时错误。
【参考方案1】:
使用constant()函数:
$id = constant("ThingIDs::$thing");
【讨论】:
旁注:如果要先检查常量是否定义,则为defined("ThingIDs::$thing");
或 $id = constant("self::$thing");
与此类似,$id = constant(sprintf('%s::%s', ThingIDs::class, $thing));
@DavidBaucum 你为什么要过度复杂化呢?该请求非常简单,不涉及外部的、用户可操作的输入。除此之外,您正在调用另一个函数,因为我猜您不喜欢将字符串与分隔符连接起来?
根据您的用例,我的解决方案不那么复杂。特别是如果您使用 PSR-4 自动加载,那么在您的代码中到处都拼写 FQDN 可能会很丑陋。通过在文件顶部使用use
,然后使用::class
方法神奇地获取FQDN,提高了可读性。【参考方案2】:
使用反射
$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
【讨论】:
反射确实提供了对类、方法等的很多洞察力,似乎很多人都害怕采取这一步来理解它们。很好的答案。 @mikemackintosh 我已采取措施了解它们,但在性能影响方面与公认的答案相比并没有看到太多。这是我有兴趣知道的。实例化一个新类似乎比简单地静态调用一个常量对性能的影响更大。您对此有何看法?【参考方案3】:如果你使用命名空间,你应该在类中包含命名空间。
echo constant('My\Application\ThingClass::ThingConstant');
【讨论】:
【参考方案4】:辅助函数
你可以使用这样的函数:
function class_constant($class, $constant)
if ( ! is_string($class))
$class = get_class($class);
return constant($class . '::' . $constant);
它需要两个参数:
类名或对象实例 类常量名如果传递了一个对象实例,则推断其类名。如果您使用 php 7,则可以使用 ::class
传递适当的类名,而无需考虑命名空间。
示例
class MyClass
const MY_CONSTANT = 'value';
class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)
$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'
【讨论】:
【参考方案5】:<?php
class Dude
const TEST = 'howdy';
function symbol_to_value($symbol, $class)
$refl = new ReflectionClass($class);
$enum = $refl->getConstants();
return isset($enum[$symbol])?$enum[$symbol]:false;
// print 'howdy'
echo symbol_to_value('TEST', 'Dude');
【讨论】:
【参考方案6】:如果您有对类本身的引用,那么您可以执行以下操作:
if (defined(get_class($course). '::COURSES_PER_INSTANCE'))
// class constant is defined
【讨论】:
【参考方案7】:我的问题与这个主题类似。当你有对象但没有类名时,你可以使用:
$class_name = get_class($class_object);
$class_const = 'My_Constant';
$constant_value = constant($class_name.'::'.$class_const);
【讨论】:
【参考方案8】:我知道我来晚了,但我希望这能有所帮助。
根据Phil的回答,我创建了一个可以扩展的默认枚举器类。
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'
。
函数get_called_class()
是一个返回调用该方法的类名的函数,它专门用于静态方法。
在这种情况下,$child_class
的值将是 CustomEnum::class
。 ReflectionClass 接受字符串和对象作为参数。
【讨论】:
以上是关于获取PHP中动态选择的类常量的值的主要内容,如果未能解决你的问题,请参考以下文章