it-swarm.com.de

Prüfen, ob die Klasse einer Instanz eine Schnittstelle implementiert?

Kann bei einer gegebenen Klasseninstanz festgestellt werden, ob eine bestimmte Schnittstelle implementiert ist? Soweit ich weiß, gibt es keine eingebaute Funktion, um dies direkt zu tun. Welche Optionen habe ich (falls vorhanden)?

139
Wilco
interface IInterface
{
}

class TheClass implements IInterface
{
}

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

Sie können den Operator "instanceof" verwenden. Zur Verwendung ist der linke Operand eine Klasseninstanz und der rechte Operand eine Schnittstelle. Es gibt true zurück, wenn das Objekt eine bestimmte Schnittstelle implementiert.

240
user19302

Wie von hier aus hervorhebt, können Sie class_implements() verwenden. Genau wie bei Reflection können Sie hiermit den Klassennamen als Zeichenfolge angeben und benötigen keine Instanz der Klasse:

interface IInterface
{
}

class TheClass implements IInterface
{
}

$interfaces = class_implements('TheClass');

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

class_implements() ist Teil der SPL-Erweiterung.

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

Leistungstests

Einige einfache Leistungstests zeigen die Kosten für jeden Ansatz:

Gegeben eine Instanz eines Objekts

 Objektkonstruktion außerhalb der Schleife (100.000 Iterationen) 
 ____________________________________________ 
 | class_implements | Reflexion | instanceOf | 
 | --------------- ------------ | ---------- - | 
 | 140 ms | 290 ms | 35 ms | 
 '------------------------------------- --- '
 
 Objektkonstruktion innerhalb der Schleife (100.000 Iterationen) 
 ____________________________________________ 
 | class_implements | Reflexion | instanceOf | 
 | ------------------ | ------------ | ---------- - | 
 | 182 ms | 340 ms | 83 ms | Günstiger Konstruktor 
 | 431 ms | 607 ms | 338 ms | Teurer Konstruktor 
 '------------------------------------------ -

Nur einen Klassennamen gegeben

 100.000 Iterationen 
 ____________________________________________ 
 | class_implements | Reflexion | instanceOf | 
 | ------------------ | ------------ | ---------- - | 
 | 149 ms | 295 ms | N/A | 
 '------------------------------------ ---- '

Wo das teure __construct () ist:

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

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

Diese Tests basieren auf --- (diesem einfachen Code .

94
Jess Telford

nlaq weist darauf hin, dass instanceof verwendet werden kann, um zu testen, ob das Objekt eine Instanz einer Klasse ist, die eine Schnittstelle implementiert.

Aber instanceof unterscheidet nicht zwischen einem Klassentyp und einer Schnittstelle. Sie wissen nicht, ob das Objekt eine Klasse ist, die zufällig IInterface heißt.

Sie können auch die Reflection-API in PHP verwenden, um dies genauer zu testen:

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

Siehe http://php.net/manual/en/book.reflection.php

55
Bill Karwin

Nur um zukünftige Suchen zu erleichtern is_subclass_of ist auch eine gute Variante (für PHP 5.3.7+):

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

Sie können auch Folgendes tun

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

Es wird ein behebbarer Fehler ausgegeben, wenn $objectSupposedToBeImplementing implementiert die Schnittstelle YourInterface nicht.

5
Starx