web-dev-qa-db-ja.com

クラスがPHPの特性を使用しているかどうかを確認する方法

トレイトが他のトレイトを使用する可能性があるため、クラスがそのトレイトを直接使用していない可能性があることに注意してください。また、クラスは、その特性を使用する親クラスから継承される場合もあります。

これは数行で解決できる質問ですか、それともループを実行する必要がありますか?

12
bijiDango

class_uses() 関数は、そのクラスが使用するすべての特性の名前を含む配列を返し、クラス名またはインスタンスを渡すことで機能します。ただし、次のようにする必要があります。継承ツリーを「再帰」してすべての特性を使用し、各特性も使用する

[〜#〜]編集[〜#〜]

ご了承ください stealz at op dot plは、リンクされたPHP Docsページのコメントセクションに、この再帰を行う方法を示すサンプル関数を提供しました

10
Mark Baker

特性リストで特性を確認します。

$usingTrait = in_array( MyTrait::class, array_keys((new \ReflectionClass(MyClass::class))->getTraits()) );

MyClassMyTraitを使用する場合、これはtrueまたはfalseを返します

8
Davi Menezes

これに取り組む別の方法は、あなたの特性に期待されるものを定義するインターフェースを使用することです。次に、リフレクションやダックタイピングではなく、「instanceof SomeInterface」を使用しています。

5
MeatPopsicle

以下の関数は http://php.net/manual/en/function.class-uses.php からのもので、ulfのコメントです。完璧に動作します。

function class_uses_deep($class, $autoload = true)
{
    $traits = [];

    // Get traits of all parent classes
    do {
        $traits = array_merge(class_uses($class, $autoload), $traits);
    } while ($class = get_parent_class($class));

    // Get traits of all parent traits
    $traitsToSearch = $traits;
    while (!empty($traitsToSearch)) {
        $newTraits = class_uses(array_pop($traitsToSearch), $autoload);
        $traits = array_merge($newTraits, $traits);
        $traitsToSearch = array_merge($newTraits, $traitsToSearch);
    };

    foreach ($traits as $trait => $same) {
        $traits = array_merge(class_uses($trait, $autoload), $traits);
    }

    return array_unique($traits);
}
2
bijiDango

これは私のToolsクラスにあるものです

static function 
isTrait( $object, $traitName, $autoloader = true )
{
    $ret = class_uses( $object, $autoloader ) ;
    if( is_array( $ret ) )
    {
        $ret = array_search( $traitName, $ret ) !== false ;
    }
    return $ret ;
}
1
dBags

多くの場合、使用する予定のAPIの一部が存在するかどうかを確認するだけで十分です。
method_exists ( mixed $object , string $method_name ) : bool

また、@ MeatPopsicleで言及されているように、トレイトは(マーカー)インターフェースと組み合わせて使用​​されることがよくあります。