Current Location: Home> Latest Articles> is_a() Notes when detecting interface implementation

is_a() Notes when detecting interface implementation

M66 2025-06-05

Basic usage

The basic syntax of the is_a() function is as follows:

<code> is_a(object|string $object_or_class, string $class, bool $allow_string = false): bool </code>
  • $object_or_class can be an object or a class name (a string).

  • $class is the target class or interface name to be detected.

  • $allow_string determines whether the first parameter is allowed to be a string (class name), and defaults to false .

Example:

<code> interface LoggerInterface {}

class FileLogger implements LoggerInterface {}

$logger = new FileLogger();

var_dump(is_a($logger, LoggerInterface::class)); // Output: bool(true)
</code>


Things to note

1. It detects implementation, not inheriting the parent interface on the chain

When using is_a() to check an interface, it only detects whether the object implements the interface, and does not check whether its parent class implements the interface indirectly. This is different from some static analysis tools behavior.

<code> interface A {} interface B extends A {}

class MyClass implements B {}

$obj = new MyClass();

// correct
var_dump(is_a($obj, B::class)); // bool(true)

// Also correct, because B inherits A
var_dump(is_a($obj, A::class)); // bool(true)
</code>

Conclusion: The interface inheritance chain is considered by is_a() , which is different from some ways that only check "direct" interface implementations.


2. When passing in strings as object detection, $allow_string must be enabled

If the class name string is passed in, not the object, then the third parameter $allow_string must be set to true , otherwise is_a() will always return false .

<code> interface Service {}

class ApiService implements Service {}

$className = ApiService::class;

var_dump(is_a($className, Service::class, true)); // bool(true)
</code>

Once the third parameter is omitted or set to false , the above code will return false .


3. The interface name must be a fully qualified name

When using is_a() , the interface name should be a fully qualified class name (i.e., including namespace). This is especially important when using autoloading mechanisms or more complex namespace structures.

For example:

<code> namespace App\Services;

interface PaymentInterface {}

class PayPalService implements PaymentInterface {}
</code>

Pay attention to the test:

<code> use App\Services\PayPalService; use App\Services\PaymentInterface;

$service = new PayPalService();

var_dump(is_a($service, PaymentInterface::class)); // bool(true)
</code>

Otherwise, false may be returned, especially if the interface name is wrong or the use is not imported.


4. It is not recommended to replace instanceof for object checking

Although is_a() behaves consistently with instanceof in the inspection of object instances, instanceof is better in terms of performance and code readability. For example:

<code> if ($logger instanceof LoggerInterface) { // Recommended } </code>

Unless you have to dynamically judge the class name in string form, it is recommended to use instanceof first.


5. Check whether the interface implements another interface

Although the interface itself cannot be instantiated, you can check whether one interface inherits another. This is useful when reflecting or automatically registering classes to containers.

<code> interface BaseInterface {} interface SubInterface extends BaseInterface {}

var_dump(is_a(SubInterface::class, BaseInterface::class, true)); // bool(true)
</code>

This usage is usually used with functions such as class_implements() , and is especially suitable for container scanning:

<code> $classes = ['m66.net/Service/AlphaService.php', 'm66.net/Service/BetaService.php'];

foreach ($classes as $classPath) {
// After reflecting or dynamically loading the class, check whether it implements an interface
$class = get_class_from_file($classPath); // Suppose you implement this function

 if (is_a($class, \App\Contracts\HandlerInterface::class, true)) {
    // Register Service
}

}
</code>