Respuestas:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
Puede usar el operador "instanceof". Para usarlo, el operando izquierdo es una instancia de clase y el operando derecho es una interfaz. Devuelve verdadero si el objeto implementa una interfaz particular.
Como se señala a continuación, puede usar class_implements()
. Al igual que con Reflection, esto le permite especificar el nombre de la clase como una cadena y no requiere una instancia de la clase:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
es parte de la extensión SPL.
Ver: http://php.net/manual/en/function.class-implements.php
Algunas pruebas de rendimiento simples muestran los costos de cada enfoque:
Construcción de objetos fuera del ciclo (100,000 iteraciones) ____________________________________________ El | implementaciones de clase | Reflexión | instanceOf | | ------------------ | ------------ | ------------ | El | 140 ms | 290 ms | 35 ms | '--------------------------------------------' Construcción de objetos dentro del bucle (100,000 iteraciones) ____________________________________________ El | implementaciones de clase | Reflexión | instanceOf | | ------------------ | ------------ | ------------ | El | 182 ms | 340 ms | 83 ms | Constructor barato El | 431 ms | 607 ms | 338 ms | Constructor caro '--------------------------------------------'
100,000 iteraciones ____________________________________________ El | implementaciones de clase | Reflexión | instanceOf | | ------------------ | ------------ | ------------ | El | 149 ms | 295 ms | N / A '--------------------------------------------'
Donde el costoso __construct () es:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Estas pruebas se basan en este código simple .
nlaq señala que instanceof
se puede usar para probar si el objeto es una instancia de una clase que implementa una interfaz.
Pero instanceof
no distingue entre un tipo de clase y una interfaz. No sabe si el objeto es una clase a la que se llama IInterface
.
También puede usar la API de reflexión en PHP para probar esto más específicamente:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
volver a usar de forma segura .
class_implements()
porque es obviamente más rápido llamar a class_implements y luego in_array, en lugar de hacer una reflexión completa
Solo para ayudar a futuras búsquedas is_subclass_of también es una buena variante (para PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
La is_a
función falta aquí como alternativa.
Hice algunas pruebas de rendimiento para verificar cuál de las formas indicadas es la más eficiente.
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% | ............................................
Se agregaron algunos puntos para realmente "sentir" ver la diferencia.
Generado por esto: https://3v4l.org/8Cog7
En caso de que tenga un objeto para verificar, use instance of
como se menciona en la respuesta aceptada.
En caso de que tenga una clase para verificar, use is_a
.
Dado el caso en el que desea crear una instancia de una clase basada en una interfaz que necesita, es más preformante de usar is_a
. Solo hay una excepción: cuando el constructor está vacío.
Ejemplo:
is_a(<className>, <interfaceName>, true);
Se volverá bool
. El tercer parámetro " allow_string " le permite verificar los nombres de clase sin crear instancias de la clase.