Получить значение динамически выбранного константы класса в PHP

Я хотел бы иметь возможность сделать что-то вроде этого:

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

$thing = 'Something';
$id = ThingIDs::$thing;

Это не работает Есть ли простой способ сделать что-то эквивалентное? Обратите внимание, что я застрял с классом; это в библиотеке я не могу переписать. Я пишу код, который принимает аргументы в командной строке, и мне бы очень хотелось, чтобы он брал символические имена вместо идентификаторов.

6 ответов

Решение

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

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

Использовать отражение

$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
}
Другие вопросы по тегам