instanceof
Aprenda como o operador instanceof do PHP verifica se um objeto pertence a uma classe, classe pai ou interface implementada, com exemplos e detalhes.
O Operador instanceof do PHP
instanceof é um operador de verificação de tipos do PHP. Ele retorna um boolean (true ou false) que indica se um objeto pertence a uma determinada classe — ou, de forma mais útil, se pertence a uma classe pai na cadeia de herança ou implementa uma determinada interface.
Esta página aborda a sintaxe, como o instanceof se comporta com herança e interfaces, como usá-lo com um nome de classe armazenado em uma variável, os casos extremos que costumam surpreender as pessoas (não-objetos, null, nomes de classe desconhecidos) e quando você deve utilizá-lo em vez de uma alternativa mais limpa.
Se classes e objetos são novidade para você, leia Classes e Objetos PHP primeiro.
Sintaxe
$object instanceof ClassNameA expressão é avaliada como true quando $object é uma instância de ClassName, de qualquer classe que estende ClassName, ou de qualquer classe que implementa ClassName (quando ClassName é uma interface). Caso contrário, é avaliada como false. Note que não há sintaxe de chamada de método — instanceof é um operador, como ===, não uma função.
Uma verificação 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 foi criado a partir de MyClass, portanto a primeira verificação é true. Não tem nenhuma relação com MyOtherClass, então essa verificação retorna false. As duas classes não estão relacionadas, mesmo que pareçam similares.
instanceof e herança
O verdadeiro valor do instanceof é que ele percorre a cadeia de herança. Um objeto filho é uma instância da sua classe pai, portanto a verificação é bem-sucedida para todos os ancestrais.
<?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 passa na verificação de Fruit porque Apple estende Fruit. Falha na verificação de Banana porque Apple e Banana são classes irmãs — nenhuma herda da outra. Saiba mais em Herança PHP.
instanceof e interfaces
O instanceof é mais comumente usado com interfaces. Como qualquer classe que implementa uma interface conta como uma instância dela, você pode testar uma capacidade sem se preocupar com a classe 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: ○□A string "not a shape" é ignorada porque não é um Drawable. Este é o caso de uso cotidiano: filtrar uma lista mista para os objetos que suportam o comportamento que você precisa. Veja Interfaces PHP para o quadro completo.
Usando um nome de classe de uma variável
O lado direito pode ser uma variável string contendo um nome de classe ou interface. Isso é útil quando o tipo é determinado em tempo de execução.
<?php
class Fruit {}
class Apple extends Fruit {}
$apple = new Apple();
$type = 'Fruit';
var_dump($apple instanceof $type); // bool(true)Você também pode comparar dois objetos — $a instanceof $b funciona quando $b é um objeto, verificando se $a é uma instância da classe de $b.
Casos extremos e armadilhas
instanceof nunca lança exceções e nunca emite avisos. Quando o operando da esquerda não é um objeto, simplesmente retorna 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)Isso torna o instanceof seguro para usar como guarda antes de chamar um método, sem necessidade de verificar primeiro is_object(). Se você precisa apenas saber se um valor é um objeto qualquer (de qualquer classe), use is_object() em vez disso.
Um ponto sutil: se você passar um nome de classe que não existe como literal de string no lado direito, o PHP não faz autoload nem gera erro — apenas retorna false. Portanto, um erro de digitação no nome da classe falha silenciosamente. Prefira o nome de classe diretamente ($x instanceof Fruit) em vez de uma string quando possível, para que o parser valide o nome.
Quando usar instanceof — e quando não usar
Use instanceof quando você genuinamente tem um valor cujo tipo não pode ser garantido: dados de json_decode, uma coleção mista, um plugin retornado por código do usuário, ou um bloco catch que estreita uma exceção.
<?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 inputEvite espalhar verificações instanceof pelo seu código para ramificar por tipo — longas cadeias if ($x instanceof A) … elseif ($x instanceof B) geralmente indicam que um método deveria ser definido em cada classe e chamado polimorficamente. Recorra ao instanceof para proteger uma operação, não para substituir herança.
Resumo
$object instanceof ClassNameretornatruese o objeto for uma instância da classe, de uma subclasse ou de uma interface implementada.- Ele percorre toda a cadeia de herança e corresponde a interfaces — é isso que o torna poderoso.
- Retorna
false(nunca um erro) paranull, escalares e outros não-objetos, portanto é seguro como guarda. - Um nome de classe inexistente passado como string retorna
falsesilenciosamente; prefira o nome de classe diretamente. - Use-o para verificar o tipo de um valor desconhecido antes de agir sobre ele, não como substituto para polimorfismo.