web-dev-qa-db-ja.com

PHP traits-汎用定数の定義

名前空間内のいくつかのクラスで使用される定数を定義する最良の方法は何ですか?私はあまりにも多くの継承を避けようとしているので、基底クラスを拡張することは理想的な解決策ではなく、特性を使用して良い解決策を見つけるのに苦労しています。これはPHP 5.4で可能ですか、それとも別のアプローチを取るべきですか?

次の状況があります。

trait Base
{
    // Generic functions
}

class A 
{
    use Base;
}

class B 
{
    use Base;
}

問題は、PHP traits。で定数を定義することができないということです。理想的には、次のようなものが欲しいでしょう:

trait Base
{
    const SOME_CONST = 'someconst';
    const SOME_OTHER_CONST = 'someotherconst';

    // Generic functions
}

次に、特性を適用するクラスからこれらにアクセスできます。

echo A::SOME_CONST;
echo B::SOME_OTHER_CONST;

しかし、特性の制限により、これは不可能です。何か案は?

50
Tom Jowitt

私は ser sectusの提案 を使用することになりました。 APIコントラクトではなくインターフェイスを使用して定数を保存することは悪臭がありますが、この問題は、特性の実装よりもOO設計に関するものかもしれません。

interface Definition
{
    const SOME_CONST = 'someconst';
    const SOME_OTHER_CONST = 'someotherconst';
}

trait Base
{
    // Generic functions
}

class A implements Definition
{
    use Base;
}

class B implements Definition
{
    use Base;
}

以下が可能です:

A::SOME_CONST;
B::SOME_CONST;
70
Tom Jowitt

静的変数を使用することもできます。それらは、クラスまたは特性自体で使用できます。 -constの代替として私にとっては問題なく動作します。

trait myTrait {
    static $someVarA = "my specific content";
    static $someVarB = "my second specific content";
}

class myCustomClass {
    use myTrait;

    public function hello()
    {
        return self::$someVarA;
    }
}
24
Michael

定数のスコープを制限するには、名前空間内で定数を定義できます。

namespace Test;

const Foo = 123;

// generic functions or classes

echo Foo;
echo namespace\Foo;

このアプローチの欠点は、少なくとも5.4では定数ではオートロードが機能しないことです。これを回避する典型的な方法は、これらの定数を静的クラスにラップすることです。

namespace Test;

class Bar
{
    const Foo = 123;
}
9
Ja͢ck

良いものではありませんが、多分...

trait Base
{
    public static function SOME_CONST()
    {
        return 'value1';
    }

    public static function SOME_OTHER_CONST()
    {
        return 'value2';
    }

    // generic functions
}

class A
{
    use Base;
}

class B
{
    use Base;
}

echo A::SOME_CONST();
echo B::SOME_OTHER_CONST();
4
Jekis

定数を定義し、特性関数でこの定数を返すことで、これを行うための少しハック的な方法があります。

define ('myConst','this is a constant');

trait Base {
  public function returnConst() {
    return myConst;
  }
}

class myClass {
  use Base;
}

$o = new myClass();
echo $o->returnConst();

他に考慮すべきことは、代わりに抽象クラスを使用してから継承できるかどうかです。

abstract class Base
{
    const A = 1;
    const B = 2;
}

class Class1 extends Base {}
class Class2 extends Base {}

echo Class1::A;
echo Class2::B;

もちろん、特性の理由の一部は、複雑な継承ツリーを構成に置き換えることです。状況に依存します。

0
Osan