2016-04-09 5 views
9

Я заметил, что instanceof работает с чертами тоже. Является ли это правильным способом проверить, использует ли класс определенный признак или есть ли какой-либо другой метод?PHP instanceof для черт

+10

Не так ли? По моим сведениям, это не так ('$ x instanceof SomeTrait' всегда будет ложным). – kuba

+1

Возможный дубликат [как получить привычные черты в php-классе?] (Http://stackoverflow.com/questions/13633346/how-to-get-used-traits-in-php-class) – ar34z

+1

'instanceof' is всегда ложный с признаком. черты не являются чем-то конкретным. – Raffaello

ответ

20

Хотя ничто не останавливает вас от использования instanceof с признаками, рекомендуется использовать пары с интерфейсами. Таким образом, вы должны были бы:

class Foo implements MyInterface 
{ 
    use MyTrait; 
} 

Где MyTrait является реализация MyInterface. Затем проверьте интерфейс вместо черт, как так:

if ($foo instanceof MyInterface) { 
    ... 
} 

И вы можете также ввести намек, что вы не можете с чертами:

function bar(MyInterface $foo) { 
    ... 
} 

В случае, если вы абсолютно необходимо знать, является ли класс использует определенный признак или реализацию, вы можете просто добавить к интерфейсу другой метод, который возвращает другое значение, основанное на реализации.

+1

Этот подход не является полезным в случае реализации непубличной логики. Когда, например, вам нужно создавать разные варианты поведения с простым 'use BehaviorATrait; используйте BehaviorBTrait; 'и он должен быть основан на некоторых интерфейсах защищенных методов. Наверняка это не хороший дизайн, а разговоры о гибкости инструмента. – lazycommit

+1

Вопрос о чертах, которые не могут реализовать интерфейсы. Вышеприведенный фрагмент будет работать только для классов. – Kafoso

5

Это не очень чистое и не может быть правильным решением для вашего дела. Но альтернатива, чтобы проверить, если объект или класс реализует метод Trait (как правило, не перезаписать существующие методы с Trait)

if (method_exists($my_object, 'MyTraitSpecificMethod')){ 
    ... 
} 
+0

это тоже мой взлом ... – fico7489

13

Вы можете использовать class_uses функцию, чтобы получить массив всех признаков используемый классом.

Затем вы проверяете, имеет ли этот массив ключ с тем же именем, для которого вы тестируете.

если это так, то ваш класс использует вашу черту. Если нет, то он не использует его.