is_a(object|string $object_or_class, string $class, bool $allow_string = false): bool
$object_or_class:可以是对象或类名字符串。
$class:要判断的目标类名。
$allow_string:如果传入的是类名字符串而不是对象,此参数必须设为 true。
示例:
class Animal {}
class Dog extends Animal {}
$dog = new Dog();
var_dump(is_a($dog, 'Animal')); // true
也可以传入字符串:
var_dump(is_a('Dog', 'Animal', true)); // true
$object instanceof ClassName
示例:
$dog = new Dog();
var_dump($dog instanceof Animal); // true
注意:instanceof 只能用于对象,不能直接用于类名字符串。
二者都返回布尔值,判断对象是否是某个类的实例或者子类。但是:
is_a() 更宽松,可以判断类名字符串(在 $allow_string = true 的情况下)。
instanceof 更严格,更加面向对象语义,不能判断类名字符串。
在绝大多数场景下,两者的性能差距可以忽略不计。但从语言底层角度看,instanceof 是操作符,直接作用于对象,性能略优。而 is_a() 是一个函数,有一定的调用开销。
除非你在一个非常频繁的循环中执行类型判断,否则无需太过关注这点。
is_a() 在 PHP 5 之前默认是一个行为类似的内部函数,从 PHP 5 开始正式支持当前形式。
instanceof 是语言操作符,一直以来都稳定支持。
如果你需要让代码兼容早期版本或是避免函数调用风险(如函数被覆盖、mock 等),instanceof 更可靠。
当使用用户提供的类名进行判断时,is_a() 容易被误用。例如:
$class = $_GET['class']; // 用户可能传入任意类名
if (is_a($object, $class)) {
// ...
}
这类动态判断存在一定安全隐患。使用 instanceof 更能约束类型结构,避免潜在注入或误判。
建议优先使用 instanceof,理由如下:
更加语义化、符合面向对象编程风格。
更少的错误风险,更清晰的类型逻辑。
性能略优,表达更简洁。
在少数需要动态传入类名(如工厂模式、插件机制)时,可使用 is_a(),但要明确地设置 $allow_string = true,并确保传入的类名是安全可信的。
例如:
$class = 'App\\Plugins\\SomeHandler';
if (is_a($handler, $class, true)) {
$handler->handle();
}
可参考的动态插件管理示例代码托管在:
https://m66.net/examples/plugin-loader.php