instanceof 運算子與 is_a() 函式功能相同:判斷物件是否屬於某類別、或該類別是否為物件的父類別(介面)。回傳 true 或 false。但兩者在 PHP 版本演進中經歷了廢棄與恢復,理解歷史脈絡有助於做出正確選擇。
// instanceof 運算子(推薦)
if ($obj instanceof MyClass) { ... }
if ($obj instanceof MyInterface) { ... }
// is_a() 函式
if (is_a($obj, 'MyClass')) { ... }
if (is_a($obj, 'MyInterface')) { ... }
| PHP 版本 | 狀態 | 說明 |
|---|---|---|
| PHP 4 | 僅 is_a() | 早期唯一選擇 |
| PHP 5.0 | 引入 instanceof | 官方推薦替代 is_a() |
| PHP 5.0 - 5.2 | is_a() 被廢棄 | 觸發 E_DEPRECATED 警告 |
| PHP 5.3.0+ | is_a() 恢復 | 不再產生警告,但 instanceof 仍為首選 |
| PHP 7/8 | 兩者共存 | instanceof 效能略優、語意更清晰 |
instanceof 是語言關鍵字,Opcode 快取友善;is_a() 是函式呼叫,需解析字串類別名is_a('NonExistentClass') 會觸發自動載入器嘗試載入類別;instanceof NonExistentClass 編譯期即報錯is_a($obj, $className) 適合動態類別名場景;instanceof 需配合 is_subclass_of() 或 class_implements()$className = 'Some\\Dynamic\\Class';
// 方案 1:is_a() 直觀
if (is_a($obj, $className)) { ... }
// 方案 2:instanceof + 變數(PHP 5.0+)
if ($obj instanceof $className) { ... } // 支援變數
// 方案 3:ReflectionClass(需載入類別)
$ref = new ReflectionClass($className);
if ($ref->isInstance($obj)) { ... }
instanceof:語意明確、效能較好、IDE 靜態分析支援完整is_a():例如插件系統、序列化還原等場景get_class($obj) === 'ClassName':無法識別繼承關係instanceof:$obj instanceof Countableis_a() 已移除instanceof」false,不會報錯is_subclass_of()is_subclass_of() 僅檢查繼承關係,不包含自身類別總結:現代 PHP(5.3+)環境下,統一使用 instanceof 是最穩健選擇。僅在高度動態、類別名以字串形式傳遞的極少數場景考慮 is_a()。