10

今日、私は奇妙な問題に遭遇しました.PHPエンジニアとしても、これには困惑しています:

次のようなオブジェクト インスタンスからクラス定数にアクセスできるようです。

class a {
    const abc = 1;
}
$a = new a();
var_dump($a->abc);

これにより、予想される 1 ではなく null が出力されます。次のことができました。

class a {
    const abc = 1;
}
$a = new a();
var_dump(a::abc);

しかし、親が正確に誰であるかを本当に知らないサブオブジェクトのコンテキストでは、次のことを行うのは非常に面倒です。

class a {
    const abc = 1;
}
$a = new a();
$c = get_class($a);
var_dump($c::abc);

それは私ですか、それともこれは完全にばかげています。そうでない場合は、なぜそのように機能するのか教えてください。

編集

それを行う別の方法ですが、実際には良くありません:

class a {
    const abc = 1;
}
class b {
    public function getA(){
        return new a();
    }
}
$b = new b();
$c = $b->getA();
var_dump($c::abc);

この最後の例は、私がやっていることと経験していることのように機能します...

4

6 に答える 6

16

スコープ解決演算子でインスタンス変数を使用するだけです。

$a = new a();
var_dump($a::abc);

これは印刷され 1ます。

于 2012-08-15T20:37:19.140 に答える
9

問題を扱いやすくするための、比較的素晴らしくクリーンな方法を見つけました。これが私が適用した解決策です。必ずしも最高というわけではありませんが、私の用途では、必要なことを正確に実行します。

魔法の __get メソッドを作成することで、インスタンスの観点から定数名の要求をインターセプトし、クイック リフレクションを使用してその定数が存在するかどうかを確認し、その値を返します。

これにより、実際には次のようなパターンをすべて 1 行で使用できます。

class a {
    const abc = 1;
    public function __get($key){
        $r = new ReflectionObject($this);
        if($r->hasConstant($key)){ return $r->getConstant($key); }
    }
}
class b {
    public function getA(){
        return new a();
    }
}
$b = new b();
var_dump($b->getA()->abc);
var_dump($b->getA()->def);

私はやりたかったのですが:

var_dump($b->getA()::abc);
var_dump($b->getA()::def);

最終的に配列の逆参照があることを考えると、5.4以降でこれが可能になる可能性があると思います。おそらく、すぐに静的な逆参照を追加するように依頼することができます。

于 2012-08-15T20:54:39.913 に答える
4

PHPのドキュメント::には、クラス定数は。ではなくSRO()を介してアクセスされることが示されています->

<?php
class MyClass
{
    const constant = 'constant value';

    function showConstant() {
        echo  self::constant . "\n";
    }
}

echo MyClass::constant . "\n";
于 2012-08-15T20:39:01.080 に答える
3

前述のように、php の定数はクラス定義に関連付けられており、定義上静的であり、-> 演算子を使用してアクセスすることはできません。

コーディング パラダイムで本当に使用したい場合は、php5 のリフレクション クラスを試すことができます。

class MyClass
{
   const A = "I am A";
}

$o = new ReflectionClass( "MyClass" );
echo $o->getconstant("A"); //will print "I am A"

また、あなたのEDITの例はうまくいかないかもしれないと思います..私はそれを実行しませんでしたが、クラス参照ではないもので SRO(::) を呼び出すことができるかどうかはわかりません..

于 2012-08-15T22:07:40.223 に答える
2

これが古いスレッドであることは承知していますが、これを行う最善の方法を知りたい人は、PHP 関数のconstant()を参照してください。

constant() を使用すると、次のように簡単に実行できます。

$a = new a();
$value = constant(get_class($a)."::abc");
// $value === 1

これは PHP 4 以降で利用可能で、PHP 5.5 でも完全に動作します。

于 2013-11-05T18:17:23.070 に答える