web-dev-qa-db-ja.com

インスタンスのクラスがインターフェースを実装しているかどうかを確認していますか?

クラスインスタンスを指定すると、特定のインターフェイスを実装しているかどうかを判断できますか?私の知る限り、これを直接行う組み込み関数はありません。どのようなオプションがありますか(ある場合)?

139
Wilco
interface IInterface
{
}

class TheClass implements IInterface
{
}

$cls = new TheClass();
if ($cls instanceof IInterface) {
    echo "yes";
}

「instanceof」演算子を使用できます。これを使用するには、左のオペランドがクラスインスタンスで、右のオペランドがインターフェイスです。オブジェクトが特定のインターフェイスを実装する場合、trueを返します。

240
user19302

therefromhere が指摘しているように、class_implements()を使用できます。 Reflectionと同様に、これによりクラス名を文字列として指定でき、クラスのインスタンスは必要ありません。

_interface IInterface
{
}

class TheClass implements IInterface
{
}

$interfaces = class_implements('TheClass');

if (isset($interfaces['IInterface'])) {
    echo "Yes!";
}
_

class_implements()は、SPL拡張機能の一部です。

参照: http://php.net/manual/en/function.class-implements.php

性能試験

いくつかの簡単なパフォーマンステストは、各アプローチのコストを示しています。

オブジェクトのインスタンスを指定

ループ外のオブジェクト構築(100,000回の繰り返し)
 ____________________________________________ 
 | class_implements |リフレクション| instanceOf | 
 | --------------- ------------ | ---------- -| 
 | 140ミリ秒| 290ミリ秒| 35ミリ秒| 
 '----------------------------------------- --- '
 
ループ内のオブジェクト構築(100,000回の繰り返し)
 ____________________________________________ 
 | class_implements |リフレクション| instanceOf | 
 | ------------------ | ------------ | ---------- -| 
 | 182ミリ秒| 340ミリ秒| 83ミリ秒|安いコンストラクター
 | 431ミリ秒| 607ミリ秒| 338ミリ秒|高価なコンストラクタ
 '------------------------------------------ -'

クラス名のみを指定

 100,000回の反復
 ____________________________________________ 
 | class_implements |リフレクション| instanceOf | 
 | ------------------ | ------------ | ---------- -| 
 | 149ミリ秒| 295ミリ秒|なし| 
 '---------------------------------------- ---- '

高価な__construct()は次のとおりです。

_public function __construct() {
    $tmp = array(
        'foo' => 'bar',
        'this' => 'that'
    );  

    $in = in_array('those', $tmp);
}
_

これらのテストは---(この単純なコード に基づいています。

94
Jess Telford

nlaqは、instanceofを使用して、オブジェクトがインターフェイスを実装するクラスのインスタンスであるかどうかをテストできることを指摘しています。

ただし、instanceofはクラスタイプとインターフェイスを区別しません。オブジェクトがIInterfaceと呼ばれるclassかどうかはわかりません。

PHPでリフレクションAPIを使用して、これをより具体的にテストすることもできます。

$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
  print "Yep!\n";
}

http://php.net/manual/en/book.reflection.php を参照してください

55
Bill Karwin

将来の検索を支援するためだけに is_subclass_of も良いバリエーションです(PHP 5.3.7+)の場合:

if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
    echo 'I can do it!';
}
18
d.raev

次のこともできます

public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
   //.....
}

$objectSupposedToBeImplementingYourInterfaceインターフェイスを実装していない場合、回復可能なエラーがスローされます。

5
Starx