They overlap a lot, but they're not exactly the same. The biggest difference is that instanceof is a language operator, while is_a() is a function with some additional flexibility.
Here's how they compare.
| Feature | instanceof | is_a() |
|---|
| Checks object type | ✅ | ✅ |
| Considers inheritance | ✅ | ✅ |
| Considers implemented interfaces | ✅ | ✅ |
| Accepts class name as a string | Right-hand side only | Yes |
| Can check a class-name string without an object | ❌ | ✅ (with third parameter) |
| Performance | Slightly faster | Slightly slower (function call) |
Basic usage
These are equivalent when checking an object:
class Animal {}
class Dog extends Animal {}
$dog = new Dog();
var_dump($dog instanceof Animal); // true
var_dump(is_a($dog, Animal::class)); // true
Inheritance behaves the same in both cases.
Interfaces also work the same
interface Pet {}
class Dog implements Pet {}
$dog = new Dog();
var_dump($dog instanceof Pet); // true
var_dump(is_a($dog, Pet::class)); // true
The main difference: checking class names
is_a() has a third parameter, $allow_string.
class Animal {}
class Dog extends Animal {}
$class = Dog::class;
var_dump(is_a($class, Animal::class, true)); // true
Here, $class is just the string "Dog"—not an object. instanceof cannot do this:
$class instanceof Animal; // TypeError
Variable class names
Both support a variable containing a class name:
$class = Animal::class;
$dog instanceof $class; // true
is_a($dog, $class); // true
Why you might see "weird" inheritance behavior
Some common causes are:
- Passing a string instead of an object
$dog = Dog::class;
is_a($dog, Animal::class); // false
is_a($dog, Animal::class, true); // true
- Using aliases or different namespaces
$dog instanceof Animal;
If Animal refers to a different namespace than you intended, the check may fail even though the class names look similar.
- Objects from different inheritance trees
Two classes with the same short name but different namespaces are unrelated:
App\Models\Dog
Other\Models\Dog
These are completely different classes.
Which should you use?
In most object-oriented PHP code:
- Prefer
instanceof when you have an object and are checking its type.
- Use
is_a() when you need to work with class names as strings, especially if you're writing frameworks, dependency injection containers, or reflection-based code.
For example:
if ($object instanceof Animal) {
// Preferred
}
versus:
if (is_a($className, Animal::class, true)) {
// Useful when $className is a string
}
So if you're checking an object against a class or interface, instanceof and is_a() produce the same result with respect to inheritance and implemented interfaces. If you're seeing different behavior, it's usually because one of the values is actually a class name string rather than an object, or because of a namespace/class-loading issue.