PHP(5.4)には、配列などとして使用される特性を取得するための関数はありますか?
class myClass extends movingThings {
use bikes, tanks;
__construct() {
echo 'I\'m using the two traits:' . ????; // bikes, tanks
}
}
使用済みの特性を簡単に取得するには、class_uses()を呼び出すことができます
$usedTraits = class_uses(MyClass);
// or
$usedTraits = class_uses($myObject);
利用可能な機能を確認するときは、通常、を使用することをお勧めしますinterfaces
。インターフェースにデフォルト機能を追加するには、を使用しますtraits
。このようにして、型ヒントの恩恵を受けることもできます。
インターフェイスを実装して機能を持つオブジェクトを強制し、トレイトを使用してそのインターフェイスのデフォルトコードを実装します。
class MyClass
implements SomeInterface
{
use SomeTrait;
}
次に、次の方法でインターフェイスを確認できます。
$myObject = new MyClass();
if ($myObject instanceof SomeInterface) {
//...
}
そして、それでも型ヒントを使用します。
function someFunction( SomeInterface $object )
{
//...
}
ReflectionClassを使用して、自分で作成できます
$rc = new ReflectionClass('myClass');
$count = count($rc->getTraits());
ちょうど私の2セント=)
in_array( "CLASS_NAME", class_uses($model) )
またはPHP>5.6の場合
in_array( CLASS_NAME::class, class_uses($model) )
class-uses(<class>)
の即時の特性を取得します<class>
が、親クラスまたは特性の特性などを介してすべての継承された特性を取得するわけではありません...
クラスで完全にすべての継承された特性を取得する必要がある場合は、ここの公式ドキュメントのコメントを読むことをお勧めします:
class_uses
ReflectionClass->getTraits
子クラスから特性を取得したい場合は機能しません。
例。
trait A {}
class Mother {
use A;
}
class Child extends Mother {}
var_dump(class_uses('Child')); // empty array
var_dump(class_uses('Mother')); // has A
私はこの問題を抱えているので、クラスからすべての特性を取得するための簡単なコードを記述します。
function all_class_uses($model)
{
$class = new ReflectionClass($model);
$traits = $class->getTraits();
while($parent = $class->getParentClass()) {
$traits += $class->getTraits();
$class = $parent;
}
return array_combine(array_keys($traits), array_keys($traits));
}
私はそれが役立つことを願っています(インターフェースの使用についてMauriceに感謝します):
interface IHaveHasTrait
{
public function has_trait($name);
};
trait THaveHasTrait
{
public function has_trait($name)
{
$classes = class_parents( $this );
$classes[] = get_class( $this );
foreach( $classes as $class ) {
foreach( class_uses( $class ) as $t ) {
if( $t === $name ) {
return true;
}
}
}
return false;
}
};
trait TLinkedListItem
{
use THaveHasTrait;
public $next;
public $prev;
};
class A implements IHaveHasTrait
{
use TLinkedListItem;
public $text;
public function __construct( $_text )
{
$this->text = $_text;
}
};
class B extends A{};
class C extends B{};
class LinkedList
{
public function insertItem( &$item, $position=0, $relative=false )
{
if( is_a( $item, 'IHaveHasTrait' ) ) {
echo $item->has_trait( 'TLinkedListItem' ) ? 'has' : 'not';
}
}
};
$a = new C('a');
$l = new LinkedList;
$l->insertItem($a);
?>
簡単な答え:すべきではありません。特性は、ほぼ正確にコードをコピーして貼り付けます。どの特性が使用されているかを知る必要はなく、特性が何を生成するかだけを知る必要があります。
答えたくない:ReflectionClass::getTraitsを使用してください。これについては詳しく説明しません。