IS_A()は、オブジェクトが特定のクラスのインスタンスであるかどうか、またはそのクラスから継承されているかどうかを判断するために使用されます。関数の署名は次のとおりです。
is_a(object $object, string $class_name, bool $allow_string = false): bool
$オブジェクト:検出されるオブジェクト(または$ aopt_stringに応じてクラス名)。
$ class_name :ターゲットクラス名文字列。
$ aopt_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
犬と犬は同じクラスを表していますが、 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
クラス名文字列に基づいて判断を達成するには、3番目のパラメーターを渡す必要があります。
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を返します。関連するクラスがAutoloaderを介して含まれているか、ロードされていることを確認してください。
<?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();
}