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)?
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.
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
Einige einfache Leistungstests zeigen die Kosten für jeden Ansatz:
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 '------------------------------------------ -
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 .
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";
}
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!';
}
Sie können auch Folgendes tun
public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
//.....
}
Es wird ein behebbarer Fehler ausgegeben, wenn $objectSupposedToBeImplementing
implementiert die Schnittstelle YourInterface
nicht.