web-dev-qa-db-ja.com

定数の名前を取得する方法は?

クラスで定義された定数があると仮定します:

class Foo {
    const ERR_SOME_CONST = 6001;

    function bar() {
        $x = 6001;
        // need to get 'ERR_SOME_CONST'
    }
}

PHPで可能ですか?

49
Deniss Kozlovs

reflection API で取得できます

変数の値(変数の値==定数の値)に基づいて定数の名前を取得したいと考えています。クラスで定義されているすべての定数を取得し、それらをループして、それらの定数の値を変数の値と比較します。このアプローチでは、同じ値の2つの定数がある場合、必要な定数を取得できることに注意してください。

例:

class Foo {
    const ERR_SOME_CONST = 6001;
    const ERR_SOME_OTHER_CONST = 5001;

    function bar() {
        $x = 6001;
        $fooClass = new ReflectionClass ( 'Foo' );
        $constants = $fooClass->getConstants();

        $constName = null;
        foreach ( $constants as $name => $value )
        {
            if ( $value == $x )
            {
                $constName = $name;
                break;
            }
        }

        echo $constName;
    }
}

追伸:これが必要な理由を教えてもらえますか?.

57
Jan Hančič

ここに私がそれを達成するためにしたことを示します。 Jan Hancicに触発されました。

class ErrorCode
{
    const COMMENT_NEWCOMMENT_DISABLED = -4;
    const COMMENT_TIMEBETWEENPOST_ERROR = -3;
    /**
     * Get error message of a value. It's actually the constant's name
     * @param integer $value
     * 
     * @return string
     */
    public static function getErrorMessage($value)
    {
        $class = new ReflectionClass(__CLASS__);
        $constants = array_flip($class->getConstants());

        return $constants[$value];
    }
}
26
deathemperor

リフレクションあり:

$class = new ReflectionClass("Foo");
$constants = $class->getConstants();

$constantsは、Fooクラスで定義された定数のすべての名前と値を保持する配列です。

13
Davide Gualano

私はこれが古い質問であり、すべてであることを知っていますが、まだ有用な入力があると感じています。すべての列挙型が拡張する抽象クラスを使用してこれを実装しました。抽象クラスには、汎用のtoString()メソッドが含まれています。

abstract class BaseEnum{
    private final function __construct(){ }

    public static function toString($val){
        $tmp = new ReflectionClass(get_called_class());
        $a = $tmp->getConstants();
        $b = array_flip($a);

        return ucfirst(strtolower($b[$val]));
    }
}

//actual enum
final class UserType extends BaseEnum {
    const ADMIN = 10;
    const USER = 5;
    const VIEWER = 0;
}

このようにして、ベース列挙型を拡張するすべての列挙型で、出力で使用する人間が読み取れる文字列を取得できます。さらに、finalであるenumの実装は拡張できません。また、BaseEnumのコンストラクタはprivateであるため、インスタンス化することはできません。

そのため、たとえば、すべてのユーザー名とそのタイプのリストを表示すると、次のようなことができます

foreach($users as $user){
    echo "<li>{$user->name}, ".UserType::toString($user->usertype)."</li>";
}
10
rael_kid

他のすべての答えは、重要なポイントをカバーしています。しかし、クレイジーなライナーがあなたのものなら、

function getConstantName($class, $value)
{
    return array_flip((new \ReflectionClass($class))->getConstants())[$value];
}

値が実際には定数の1つではない場合を処理する必要がある場合は、余分な行を放棄できます。

function getConstantName($class, $value)
{
    $map = array_flip((new \ReflectionClass($class))->getConstants());
    return (array_key_exists($value, $map) ? $map[$value] : null);
}
8
bishop

この関数を使用して、すべての定数を配列に割り当てることができます。

$const = get_defined_constants();

その後、次の関数を使用して、配列構造を印刷できます

echo "&lt;pre&gt;";

print_r($const);

ここで詳細な説明を見ることができます www.sugunan.com

4
Kevin

警告:この方法では、プログラムすべきではありません...(youreが何をしているのかわからない場合:))

CATEGORY_の選択により定数とその数値をエコーする1行を書きました

ここにCATEGORY_ ERR_のリストがあります

foreach(get_defined_constants() as $key => $value) if(strlen($key)>5) if(substr($key, 0,5)=="ERR_") echo"<br>Found an php ERR_ constant! : ".$key."=>".$value;

そして、あなたが番号で探しているあなただけのものが欲しい場合=>私は1行の関数を作成しました:

//input parameters: CATEGORYNAME_ , #constantNumber
function getConstantName($category,$constantNumber){foreach(get_defined_constants() as $key => $value) if(strlen($key)>strlen($category)) if(substr($key, 0,strlen($category))==$category) if($value==$constantNumber) return $key; return "No constant found.";}

したがって、たとえば、64番の情報定数があります。

echo "NameOfConstant: ".getConstantName("INFO_",64);

次のようなものが出力されます:NameOfConstant: INFO_LICENSE

3
jave

OK、OK、私はすべてがすでに覆われていることを知っています:)しかし、ヤン・ハンチッチはユースケースを求めたので、私は私のものを共有します。余談:誰もがarray_flip()を使用しているようです。なぜarray_search()ではないのですか?

\ Exceptionを拡張し、具体的な例外の小さなセットの基本クラスであるクラスで必要でした。これらの具体的な例外クラスはそれぞれ、広範な例外ドメインを対象としており、いくつかの正確な例外原因を定義しています。理由?維持し、覚えておくべき例外の大群を持ちたくありません。また、例外の内臓をログファイルにダンプする例外ハンドラーセットがあります。ここでは、非常に苦痛な状況から例外の原因を解読しようとして定数名を取得する必要があります。

CLIスクリプトの例:

class AbstractException extends Exception {
    public function getName() {
        return array_search($this->getCode(), (new ReflectionClass($this))->getConstants());
    }
}

class SyntaxException extends AbstractException {
    const BAD_SYNTAX = 90;
    const REQUIRED_PARAM = 91;
    const REQUIRED_VALUE = 92;
    const VALUE_TYPE = 93;
    const VALUE_OUT_OF_BOUNDS = 94;

    public function __construct ($message = "", $code = self::BAD_SYNTAX, Exception $previous = NULL) {
        $script = basename($GLOBALS['argv'][0]);

        echo "Invalid syntax: $message \nSee: `$script --help` for more information\n";
        parent::__construct($message, $code, $previous);
    }
}

// in autoload include
set_exception_handler(function(Exception $e) {
    error_log(basename($GLOBALS['argv'][0]) . ';'. date('Y-m-d H:i:s') .';'. $e->getName() .';'. $e->getMessage() .';'. $e->getFile() .';'. $e->getLine() ."\n", 3, 'error.log');
    exit ($e->getCode());
});
2
Forseti

同じクラスのメソッドで定数値を取得する必要がある場合は、self演算子を使用するだけです。別のクラスで定数を使用する場合は、リフレクションを使用できます

class Foo {
    const ERR_SOME_CONST = 6001;

    function bar() {
        self::ERR_SOME_CONST;
    }
}
1
Andrés Sendra