2016-04-09 67 views
9

我注意到instanceof也適用於特徵。這是檢查一個班是否使用某種特質或者是否有其他方法的正確方法?PHP instanceof for traits

+10

是嗎?據我所知,它不會('$ x instanceof SomeTrait'將永遠是錯誤的)。 – kuba

+1

可能重複[如何在php-class中使用特徵?](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; 
} 

MyTraitMyInterface的實現。 然後,你檢查的接口,而不是性狀像這樣:

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

而且你還可以輸入提示,你不能與性狀:

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

如果你絕對需要知道是否一個類正在使用特定的特徵或實現,您可以在接口中添加另一個方法,該方法根據實現返回不同的值。

+1

這種方法在非公共邏輯實現的情況下沒有用處。例如,當你需要通過簡單的'使用BehaviorATrait來生成不同的行爲變體時,使用BehaviorBTrait;'它應該基於一些受保護的方法接口。 當然,這不是一個好的設計,而是一個談論工具的靈活性。 – lazycommit

+1

問題是關於特徵,它不能實現接口。上面的代碼片段只適用於類。 – Kafoso

5

它不是很乾淨,可能不適合您的情況。但是,另一種是檢查對象或類實現性狀的方法(如通常不會覆蓋特質與現有方法)

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

這也是我的黑客... – fico7489

13

可以使用class_uses函數來獲取所有特徵組成的數組由一個班級使用。

然後你檢查這個數組是否有一個與你測試的特徵名字相同的鍵。

如果是這樣,那麼你的班級正在使用你的特質。 如果沒有,那麼它沒有使用它。