is_a

Checks whether an object or class name is of a given type, or has it as a parent or interface.

Signature
is_a(mixed $object_or_class, string $class, bool $allow_string = false): bool
  • Added in PHP 4.2.0

Parameters

ParameterTypeDescription
$object_or_classmixedAn object instance, or a class name string when $allow_string is true.
$classstringThe class or interface name to test against, fully qualified.
$allow_stringoptionalbool= falseWhen false, a string first argument is rejected and no autoloader runs.

Return value

booltrue if the object or class is of type $class or has $class as one of its supertypes, false otherwise.

Errors

Does not throw. A first argument that is neither an object nor an allowed string simply returns false.

Changelog

  • PHP 5.3.9The allow_string parameter was added, letting a class name string be passed as the first argument.

is_a() is the function form of the instanceof operator, with one extra ability: given allow_string = true it can test a class name rather than an instance, which instanceof cannot do without an object or a variable holding the name.

It returns true for the exact class, for any ancestor class, and for any interface implemented anywhere up the chain. That last part is the difference from get_parent_class(), which sees only classes.

When to reach for it

  • Validating a class-string configuration value: "is this string a class that implements Handler?" — before you ever instantiate it.
  • Filtering a list of discovered class names down to those matching a contract.
  • Type checks inside a callable where you receive mixed and want a boolean rather than a thrown error.

What trips people up

The default for allow_string is false, the opposite of is_subclass_of(). Pass a class name without setting it and you get a silent false.

The $class argument is a plain string that is never resolved against use statements — write Handler::class, not 'Handler'. And traits are not types: is_a() always returns false for a trait name, no matter which classes use it. Use class_uses() there.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Validating that a class name pulled from config implements the interface your factory requires.
  • Filtering get_declared_classes() down to every class implementing a given contract.
  • Checking a mixed value's type in a guard clause where a thrown TypeError would be too harsh.

Frequently asked questions

What is the difference between is_a and instanceof?

They give the same answer for objects, but is_a() can also test a class-name string when you pass true as the third argument. instanceof is faster and is the idiomatic choice when you already hold an object.

What is the difference between is_a and is_subclass_of?

is_a() returns true when the object is the class itself; is_subclass_of() returns false in that case and only reports strict descendants. Their allow_string defaults are also opposite.

Does is_a work with traits?

No. Traits are not types, so is_a() always returns false for a trait name. Use class_uses() or class_uses() combined with class_parents() to detect traits.

More examples

Validating a class name from configuration

MailHandler passes; stdClass exists but does not implement the contract; Ghost does not exist at all. Checking class_exists() first keeps the autoloader out of it for obviously bad names.

Example · php
<?php
interface Handler { public function handle(): string; }
class MailHandler implements Handler {
    public function handle(): string { return 'mailed'; }
}

foreach (['MailHandler', 'stdClass', 'Ghost'] as $name) {
    $ok = class_exists($name) && is_a($name, Handler::class, true);
    echo $name, ': ', $ok ? 'usable' : 'rejected', "\n";
}

is_a versus instanceof versus traits

instanceof and is_a() agree on the interface. The trait check returns false from is_a() because traits are not types — class_uses() is the right tool. Non-objects and unknown names return false rather than erroring.

Example · php
<?php
trait Loggable {}
interface Jsonish {}
class Doc implements Jsonish { use Loggable; }

$d = new Doc();
var_dump($d instanceof Jsonish, is_a($d, Jsonish::class));
var_dump(is_a($d, 'Loggable'));
var_dump(in_array('Loggable', class_uses($d), true));
var_dump(is_a(null, 'Doc'), is_a('not a class', 'Doc', true));

Discussion

  • Be the first to comment on this lesson.