is_a()用於判斷一個對像是否是某個類的實例,或者是否繼承自該類。函數簽名如下:
is_a(object $object, string $class_name, bool $allow_string = false): bool
$object :要檢測的對象(或者類名,取決於$allow_string )。
$class_name :目標類名字符串。
$allow_string :是否允許第一個參數為類名字符串而非對象,默認為false 。
例如:
class Animal {}
class Dog extends Animal {}
$dog = new Dog();
var_dump(is_a($dog, 'Animal')); // true
var_dump(is_a($dog, 'Dog')); // true
PHP 類名是不區分大小寫的,但是is_a()判斷時傳入的類名字符串,大小寫可能會導致混淆,尤其是動態傳入類名時。
示例:
$className = 'dog'; // 小寫
var_dump(is_a($dog, $className)); // false
儘管Dog和dog代表同一個類,但由於is_a()的實現機制,這裡返回false 。
解決方案:
確保動態傳入的類名使用正確的大小寫,或者統一轉為類的真實名稱。可以用get_class()或class_exists()先驗證:
$className = 'dog';
if (class_exists(ucfirst($className))) {
$className = ucfirst($className);
}
var_dump(is_a($dog, $className)); // true
當第一個參數是類名字符串時,默認is_a()不會進行判斷,而是返回false 。
var_dump(is_a('Dog', 'Animal')); // false
要實現基於類名字符串的判斷,需要傳入第三個參數true :
var_dump(is_a('Dog', 'Animal', true)); // true
這在某些依賴於字符串動態判斷類關係的場景下非常重要。
動態類名經常包含命名空間,這時必須使用完整的命名空間類名。
namespace m66\Animals;
class Dog {}
$dog = new Dog();
var_dump(is_a($dog, 'm66\Animals\Dog')); // true
如果動態傳入的類名沒有包含命名空間,則會導致判斷失敗。
如果動態傳入的類名還未被加載, is_a()也會返回false 。確保相關類已經被包含或通過自動加載器加載。
<?php
namespace m66\net;
class Animal {}
class Dog extends Animal {}
function checkInstance($obj, $dynamicClassName)
{
// 規範動態類名
$dynamicClassName = trim($dynamicClassName);
if (!class_exists($dynamicClassName)) {
// 假設自動加載機制,這裡簡化為拋錯
throw new \Exception("Class $dynamicClassName 不存在");
}
return is_a($obj, $dynamicClassName);
}
$dog = new Dog();
try {
$result = checkInstance($dog, 'm66\net\Animal');
echo $result ? '是 Animal 或其子類' : '不是 Animal 類';
} catch (\Exception $e) {
echo $e->getMessage();
}