Получить имена констант класса в php? - PullRequest
2 голосов
/ 18 мая 2010

У меня есть класс php с некоторыми константами класса, которые указывают на состояние экземпляра.

Когда я использую класс, после того, как я запускаю на нем несколько методов, я делаю некоторые проверки, чтобы убедиться, что статус соответствует ожидаемому.

Например, после вызова некоторых методов я ожидаю, что статус будет MEANINGFUL_STATUS_NAME.

$objInstance->method1();
$objInstance->method2();
if ( $objInstance->status !==  class::MEANINGFUL_STATUS_NAME ) { 
    throw new Exception("Status is wrong, should not be " . class::MEANINGFUL_STATUS_NAME . ".");
}

Однако, это дает мне сообщение об исключении

"Status is wrong, should not be 2"

когда я действительно хочу увидеть

"Status is wrong, should not be MEANINGFUL_STATUS_NAME"

Так что я потерял смысл имени константы. Я думал о создании массива «таблица перевода», чтобы я мог взять постоянные значения и перевести их обратно в их имя, но это кажется громоздким. Как мне перевести это обратно, чтобы я получил сообщение об ошибке, которое дает мне лучшее представление о том, что пошло не так?

Ответы [ 3 ]

5 голосов
/ 18 мая 2010

Это довольно хитрое решение:

$r = new ReflectionClass("YourClassName");
$constantNames = array_flip($r->getConstants());

$objInstance->method1();   
$objInstance->method2();   
if ( $objInstance->status !== YourClassName::MEANINGFUL_STATUS_NAME ) {    
    throw new Exception("Status is wrong, should not be " . $constantNames[YourClassName::MEANINGFUL_STATUS_NAME] . ".");   
} 
1 голос
/ 18 мая 2010

Мне приходит в голову, что я могу использовать строки в качестве значений для констант. Я привык видеть цифры. Есть ли причина, по которой я не должен этого делать или почему это не сработает?

0 голосов
/ 26 октября 2010

Другой способ - позволить объекту проверить, находится ли статус в требуемом режиме.

Если это не так, метод объекта может выдать исключение.

Не проверенный пример:

class Klasse
{
    const WANTED_VALUE    =  1;
    const UNWANTED_VALUE  =  2;

    private static $constant_names  =  array();
    p... function __construct ()
    {
        if ( empty( self::$constant_names ) )
        {
            $class            =  new ReflectionClass( __CLASS__ );
            $constants        =  $class->getConstants();
            $constants        =  array_flip( $constants );// requires the constant's values to be unique
            self::$constants  =  $constants;
        }
    }
    public function checkNeededStatus ()
    {
        $needed_status  =  self::WANTED_VALUE;// could also be a parameter(an argument) with a default value
        if ( $this->status !== $needed_status )
        {
            $constant_name  =  self::$constants[ $this->status ];
            $message        =  'Status is wrong, '
                . 'should not be: `' . $constant_name . '`.'
            ;
            //$message .=  '(it should be `' . self::$constants[ $needed_status ] . '`)';
            throw new Exception( $message );
        }
    }
}

$objInstance  =  new Klasse();
$objInstance->method1();
$objInstance->method2();
$objInstance->checkNeededStatus();

кредит:

Возможно, было бы неплохо рассмотреть вопрос об использовании Reflection. Поскольку брошенное сообщение остается внутри класса, с большей вероятностью это обойдется без значительного снижения удобства обслуживания.

...