Réponses:
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ète
Juste pour aider les recherches futures, is_subclass_of est également une bonne variante (pour PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
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.
instanceof [object] took 7.67 ms | + 0% | ..........
is_a [object] took 12.30 ms | + 60% | ................
is_a [class] took 17.43 ms | +127% | ......................
class_implements [object] took 28.37 ms | +270% | ....................................
reflection [class] took 34.17 ms | +346% | ............................................
Ajout de quelques points pour réellement "sentir" voir la différence.
Généré par ceci: https://3v4l.org/8Cog7
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
.
É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.