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