Подтвердить что ты не робот

Как получить привычные черты в php-классе?

Есть ли какая-либо функция в PHP (5.4), чтобы использовать используемые черты как массив или аналогичный:

class myClass extends movingThings {
  use bikes, tanks;

  __construct() {
    echo 'I\'m using the two traits:' . ????; // bikes, tanks
  }
}
4b9b3361

Ответ 1

Чтобы легко получить используемые черты, вы можете вызвать 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 )
{ 
    //...
}

Ответ 2

Вы можете написать это самостоятельно, используя ReflectionClass

$rc = new ReflectionClass('myClass');
$count = count($rc->getTraits());

Ответ 3

Только мои 2 цента =)

in_array( "CLASS_NAME", class_uses($model) ) 

Или с PHP > 5.6

in_array( CLASS_NAME::class, class_uses($model) )

Ответ 4

class-uses(<class>) получит непосредственные черты <class>, однако он не получит все унаследованные черты через родительские классы или черты признаков и т.д.

Если вам нужно получить абсолютно все унаследованные черты в классе, я бы рекомендовал прочитать комментарии в официальных документах здесь:

http://php.net/manual/en/function.class-uses.php

Ответ 5

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));
}

Ответ 6

Я хочу, чтобы это было полезно (благодаря 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);
    ?>

Ответ 7

Короткий ответ: вы не должны. Черты почти точно копируют и вставляют код. Вам НЕ НУЖНО знать, какие черты используются, только на том, что генерирует признаки.

Ответ. Я не хочу давать: используйте ReflectionClass:: getTraits. Я не собираюсь подробно останавливаться на этом.