Est-il possible de déterminer si une instance de classe implémente une interface particulière? Autant que je sache, il n'y a pas de fonction intégrée pour le faire directement. Quelles sont mes options (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 à partir de là indique, vous pouvez utiliser class_implements()
. Comme avec Reflection, cela vous permet de spécifier le nom de la classe en tant que 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'objet en dehors de la boucle (100 000 itérations) ____________________________________________ | class_implements | Réflexion | instanceOf | | --------------- ------------ | ---------- - | | 140 ms | 290 ms | 35 ms | '--------------------------------------------- --- ' Construction d'objet à 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 | Cher constructeur '---------------------------------------------- - '
100 000 itérations ____________________________________________ | class_implements | Réflexion | instanceOf | | ------------------ | ------------ | ---------- - | | 149 ms | 295 ms | N/A | '------------------------------------------------ ---- '
Où la coûteuse __construct () 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 que instanceof
peut être utilisé pour vérifier si l'objet est une instance d'une classe implémentant 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 appelée IInterface
.
Vous pouvez également utiliser l'API de réflexion dans PHP pour tester cela plus spécifiquement:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
Juste pour aider les recherches futures is_subclass_of est aussi une bonne variante (pour PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
Vous pouvez aussi faire ce qui suit
public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
//.....
}
Il y aura une erreur récupérable si le $objectSupposedToBeImplementing
n'implémente pas YourInterface
interface.