Étant donné une instance de classe, est-il possible de déterminer si elle implémente une interface particulière? Pour autant que je sache, il n'y a pas de fonction intégrée pour le faire directement. Quelles options ai-je (le cas échéant)?
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
Vous pouvez utiliser l'opérateur "instanceof". Pour l'utiliser, l'opérande gauche est une instance de classe et l'opérande droit est une interface. Il renvoie true si l'objet implémente une interface particulière.
Comme therefromhere souligne, vous pouvez utiliser class_implements()
. Tout comme avec Reflection, cela vous permet de spécifier le nom de la classe sous forme de chaîne et ne nécessite pas d'instance de la classe:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
fait partie de l'extension SPL.
Voir: http://php.net/manual/en/function.class-implements.php
Quelques tests de performance simples montrent les coûts de chaque approche:
Construction d'objets en dehors de la boucle (100 000 itérations) ____________________________________________ | class_implements | Réflexion | instanceOf | | ------------------ | ------------ | ------------ | | 140 ms | 290 ms | 35 ms | «--------------------------------------------» Construction d'objets à l'intérieur de la boucle (100 000 itérations) ____________________________________________ | class_implements | Réflexion | instanceOf | | ------------------ | ------------ | ------------ | | 182 ms | 340 ms | 83 ms | Constructeur pas cher | 431 ms | 607 ms | 338 ms | Constructeur cher «--------------------------------------------»
100 000 itérations ____________________________________________ | class_implements | Réflexion | instanceOf | | ------------------ | ------------ | ------------ | | 149 ms | 295 ms | N / A | «--------------------------------------------»
Où le __construct () coûteux est:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Ces tests sont basés sur ce code simple .
nlaq souligne qu'il instanceof
peut être utilisé pour tester si l'objet est une instance d'une classe qui implémente une interface.
Mais instanceof
ne fait pas la distinction entre un type de classe et une interface. Vous ne savez pas si l'objet est une classe qui est appelée IInterface
.
Vous pouvez également utiliser l'API de réflexion en PHP pour tester cela plus spécifiquement:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
.class_implements()
car il est évidemment plus rapide d'appeler class_implements puis in_array, au lieu de faire une réflexion complèteJuste pour aider les recherches futures, is_subclass_of est également une bonne variante (pour PHP 5.3.7+):
la source
Vous pouvez également faire ce qui suit
Il lancera une erreur récupérable si le
$objectSupposedToBeImplementing
n'implémente pas l'YourInterface
interface.la source
Mettre à jour
La
is_a
fonction manque ici comme alternative.J'ai fait quelques tests de performance pour vérifier laquelle des méthodes indiquées est la plus performante.
Résultats sur 100 000 itérations
Ajout de quelques points pour réellement "sentir" voir la différence.
Généré par ceci: https://3v4l.org/8Cog7
Conclusion
Dans le cas où vous avez un objet à vérifier, utilisez
instance of
comme mentionné dans la réponse acceptée.Si vous avez une classe à vérifier, utilisez
is_a
.Prime
Étant donné le cas où vous souhaitez instancier une classe basée sur une interface dont vous avez besoin, il est plus préformant à utiliser
is_a
. Il n'y a qu'une seule exception - lorsque le constructeur est vide.Exemple:
is_a(<className>, <interfaceName>, true);
Il reviendra
bool
. Le troisième paramètre " allow_string " lui permet de vérifier les noms de classe sans instancier la classe.la source