トレイトが他のトレイトを使用する可能性があるため、クラスがそのトレイトを直接使用していない可能性があることに注意してください。また、クラスは、その特性を使用する親クラスから継承される場合もあります。
これは数行で解決できる質問ですか、それともループを実行する必要がありますか?
class_uses() 関数は、そのクラスが使用するすべての特性の名前を含む配列を返し、クラス名またはインスタンスを渡すことで機能します。ただし、次のようにする必要があります。継承ツリーを「再帰」してすべての特性を使用し、各特性も使用する
[〜#〜]編集[〜#〜]
ご了承ください stealz at op dot pl
は、リンクされたPHP Docsページのコメントセクションに、この再帰を行う方法を示すサンプル関数を提供しました
特性リストで特性を確認します。
$usingTrait = in_array( MyTrait::class, array_keys((new \ReflectionClass(MyClass::class))->getTraits()) );
MyClassがMyTraitを使用する場合、これはtrueまたはfalseを返します
これに取り組む別の方法は、あなたの特性に期待されるものを定義するインターフェースを使用することです。次に、リフレクションやダックタイピングではなく、「instanceof SomeInterface」を使用しています。
以下の関数は 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);
}
これは私の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 ;
}
多くの場合、使用する予定のAPIの一部が存在するかどうかを確認するだけで十分です。method_exists ( mixed $object , string $method_name ) : bool
また、@ MeatPopsicleで言及されているように、トレイトは(マーカー)インターフェースと組み合わせて使用されることがよくあります。