instanceof
Aprende cómo el operador instanceof de PHP comprueba si un objeto pertenece a una clase, clase padre o interfaz implementada, con ejemplos y advertencias.
El operador instanceof de PHP
instanceof es un operador de verificación de tipos en PHP. Devuelve un boolean (true o false) que indica si un objeto pertenece a una clase determinada — o, más útilmente, si pertenece a una clase padre en la cadena de herencia o implementa una interfaz determinada.
Esta página cubre la sintaxis, cómo se comporta instanceof con la herencia y las interfaces, cómo usarlo con un nombre de clase almacenado en una variable, los casos extremos que sorprenden a la gente (no objetos, null, nombres de clase desconocidos) y cuándo deberías usarlo frente a una alternativa más limpia.
Si las clases y objetos son nuevos para ti, lee primero Clases y Objetos de PHP.
Sintaxis
$object instanceof ClassNameLa expresión se evalúa como true cuando $object es una instancia de ClassName, de cualquier clase que extienda ClassName, o de cualquier clase que implemente ClassName (cuando ClassName es una interfaz). En caso contrario, se evalúa como false. Ten en cuenta que no hay sintaxis de llamada a método — instanceof es un operador, como ===, no una función.
Una verificación básica
<?php
class MyClass {}
class MyOtherClass {}
$object = new MyClass();
if ($object instanceof MyClass) {
echo "The object is an instance of MyClass.";
} else {
echo "The object is not an instance of MyClass.";
}
// Output: The object is an instance of MyClass.
var_dump($object instanceof MyOtherClass);
// Output: bool(false)$object fue creado a partir de MyClass, por lo que la primera verificación es true. No tiene ninguna relación con MyOtherClass, por lo que esa verificación es false. Las dos clases no están relacionadas, aunque parezcan similares.
instanceof y la herencia
El verdadero valor de instanceof es que recorre la cadena de herencia. Un objeto hijo es una instancia de su clase padre, por lo que la verificación tiene éxito para todos los ancestros.
<?php
class Fruit {}
class Apple extends Fruit {}
class Banana extends Fruit {}
$apple = new Apple();
var_dump($apple instanceof Apple); // bool(true) — its own class
var_dump($apple instanceof Fruit); // bool(true) — its parent class
var_dump($apple instanceof Banana); // bool(false) — a sibling class$apple pasa la verificación de Fruit porque Apple extiende Fruit. Falla la verificación de Banana porque Apple y Banana son clases hermanas — ninguna hereda de la otra. Aprende más en Herencia de PHP.
instanceof e interfaces
instanceof se usa más comúnmente con interfaces. Debido a que cualquier clase que implementa una interfaz cuenta como una instancia de ella, puedes verificar una capacidad sin importarte la clase concreta.
<?php
interface Drawable {
public function draw(): string;
}
class Circle implements Drawable {
public function draw(): string { return "○"; }
}
class Square implements Drawable {
public function draw(): string { return "□"; }
}
$shapes = [new Circle(), new Square(), "not a shape"];
foreach ($shapes as $shape) {
if ($shape instanceof Drawable) {
echo $shape->draw();
}
}
// Output: ○□El string "not a shape" se omite porque no es un Drawable. Este es el caso de uso cotidiano: filtrar una lista mixta para quedarse solo con los objetos que soportan el comportamiento que necesitas. Consulta Interfaces de PHP para ver el panorama completo.
Usar un nombre de clase desde una variable
El lado derecho puede ser una variable string que contenga un nombre de clase o interfaz. Esto es útil cuando el tipo se determina en tiempo de ejecución.
<?php
class Fruit {}
class Apple extends Fruit {}
$apple = new Apple();
$type = 'Fruit';
var_dump($apple instanceof $type); // bool(true)También puedes comparar dos objetos — $a instanceof $b funciona cuando $b es un objeto, verificando si $a es una instancia de la clase de $b.
Casos extremos y advertencias
instanceof nunca lanza excepciones ni emite advertencias. Cuando el operando izquierdo no es un objeto, simplemente devuelve false.
<?php
class Fruit {}
var_dump(null instanceof Fruit); // bool(false)
var_dump("Fruit" instanceof Fruit); // bool(false) — a string is not an object
var_dump(42 instanceof Fruit); // bool(false)Esto hace que instanceof sea seguro para usar como guardia antes de llamar a un método, sin necesidad de comprobar primero is_object(). Si solo necesitas saber si un valor es un objeto en general (cualquier clase), usa is_object() en su lugar.
Un punto sutil: si pasas un nombre de clase que no existe como literal de string en el lado derecho, PHP no realiza autoload ni genera un error — simplemente devuelve false. Por lo tanto, un error tipográfico en el nombre de la clase falla silenciosamente. Prefiere el nombre de clase desnudo ($x instanceof Fruit) sobre un string cuando puedas, para que el analizador lo valide.
Cuándo usar instanceof — y cuándo no
Usa instanceof cuando genuinamente tienes un valor cuyo tipo no puedes garantizar: datos de json_decode, una colección mixta, un plugin devuelto por código de usuario, o un bloque catch que restringe una excepción.
<?php
try {
throw new InvalidArgumentException("bad input");
} catch (Exception $e) {
if ($e instanceof InvalidArgumentException) {
echo "Caught an argument error: " . $e->getMessage();
}
}
// Output: Caught an argument error: bad inputEvita dispersar verificaciones de instanceof por tu código para ramificar por tipo — las largas cadenas if ($x instanceof A) … elseif ($x instanceof B) generalmente indican que un método debería estar definido en cada clase y llamarse polimórficamente. Recurre a instanceof para proteger una operación, no para reemplazar la herencia.
Resumen
$object instanceof ClassNamedevuelvetruesi el objeto es una instancia de la clase, una subclase, o una interfaz implementada.- Recorre la cadena de herencia completa y coincide con interfaces — eso es lo que lo hace poderoso.
- Devuelve
false(nunca un error) paranull, escalares y otros no objetos, por lo que es seguro como guardia. - Un nombre de clase inexistente pasado como string devuelve
falsesilenciosamente; prefiere el nombre de clase desnudo. - Úsalo para verificar el tipo de un valor desconocido antes de actuar sobre él, no como sustituto del polimorfismo.