在PHP 中, is_a()函數是用來檢測一個對像是否屬於某個類或者類的子類,語法如下:
is_a(object $object, string $class_name, bool $allow_string = false): bool
其中,第一個參數必須是對像或對象名,第二個參數是類名。如果把這兩個參數順序顛倒,代碼會產生什麼後果呢?本文將通過實例來分析is_a()用錯參數順序時的表現與潛在風險。
假設有如下兩個類:
class Animal {}
class Dog extends Animal {}
$dog = new Dog();
var_dump(is_a($dog, 'Animal')); // true,Dog 是 Animal 的子類
var_dump(is_a($dog, 'Dog')); // true,$dog 是 Dog 的實例
這段代碼中, is_a($dog, 'Animal')會返回true ,表示$dog對象確實屬於Animal這個類或其子類。
如果把參數順序反過來寫,比如:
var_dump(is_a('Animal', $dog)); // 錯誤示範
這時會發生什麼呢?讓我們分析:
第一個參數是字符串'Animal' ,而不是對象。
第二個參數是對象$dog ,而不是類名字符串。
根據is_a()的定義,函數期望第一個參數是對象,第二個參數是字符串類名,順序顛倒導致類型不匹配。
PHP 7.2 及以上版本會拋出警告或錯誤,例如:
Warning: is_a() expects parameter 1 to be object, string given
函數返回false ,無法得到正確判斷。
代碼邏輯失效,導致判斷失敗。
示例代碼:
$dog = new Dog();
var_dump(is_a('Animal', $dog)); // false,且產生警告
is_a()允許第三個參數$allow_string設置為true ,以支持第一個參數傳入類名字符串而非對象:
var_dump(is_a('Dog', 'Animal', true)); // true,判斷 Dog 是否繼承 Animal
但是即使在這種情況下,第二個參數仍必須是字符串類名,顛倒順序仍然出錯:
var_dump(is_a('Animal', $dog, true)); // 依然錯誤,參數順序顛倒
is_a()函數的第一個參數必須是對象(或者當$allow_string為true時,是類名字符串),第二個參數必須是類名字符串。
顛倒參數順序會導致類型不匹配,PHP 會報警告並返回false ,判斷失效。
開發中應特別注意參數順序,避免因傳參錯誤而導致難以發現的邏輯漏洞。