Получить значение динамически выбранного константы класса в PHP
Я хотел бы иметь возможность сделать что-то вроде этого:
class ThingIDs
{
const Something = 1;
const AnotherThing = 2;
}
$thing = 'Something';
$id = ThingIDs::$thing;
Это не работает Есть ли простой способ сделать что-то эквивалентное? Обратите внимание, что я застрял с классом; это в библиотеке я не могу переписать. Я пишу код, который принимает аргументы в командной строке, и мне бы очень хотелось, чтобы он брал символические имена вместо идентификаторов.
6 ответов
$id = constant("ThingIDs::$thing");
Использовать отражение
$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
Если вы используете пространства имен, вы должны включить пространство имен в класс.
echo constant('My\Application\ThingClass::ThingConstant');
Вспомогательная функция
Вы можете использовать такую функцию:
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'
<?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');
Моя проблема была похожа на эту тему. Когда у вас есть объект, но нет имени класса, вы можете использовать:
$class_name = get_class($class_object);
$class_const = 'My_Constant';
$constant_value = constant($class_name.'::'.$class_const);
Я знаю, что немного опоздала, но надеюсь, что это все равно поможет.
Основываясь на ответе 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 принимает строки и объект в качестве параметра.
Если у вас есть ссылка на сам класс, то вы можете сделать следующее:
if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
// class constant is defined
}