PHPでは、 IS_A()関数を使用して、オブジェクトが特定のクラスに属しているのかそのサブクラスに属しているのかを判断することがよくあります。ただし、クラスが名前空間を使用すると、多くの開発者がIS_A()判断がしばしば故障し、コードロジックの例外が生じることがわかります。この記事では、この現象の理由と、 IS_a()を使用して名前空間でクラスを判断する方法を詳細に分析します。
IS_A()は、PHPの組み込み関数であり、署名は次のとおりです。
is_a(object|string $object_or_class, string $class_name, bool $allow_string = false): bool
最初のパラメーターが2番目のパラメーターの指定クラスのインスタンスかそのサブクラスであるかを決定します。例:
class Animal {}
class Dog extends Animal {}
$dog = new Dog();
var_dump(is_a($dog, 'Animal')); // true
名前空間の導入により、クラスの「完全な資格のある名前」(FQN)の概念が変更されました。例えば:
namespace MyApp\Models;
class User {}
現時点では、ユーザークラスのクラス名全体の名前はMyApp \ Models \ユーザーであり、単純なユーザーではありません。 is_a($ obj、 'user')を直接使用すると、実際に$ objがグローバルネームスペースの下でユーザークラスに属しているかどうかを判断します。これにより、判断が失敗します。
次のコードがあるとします。
namespace MyApp\Models;
class User {}
$user = new User();
var_dump(is_a($user, 'User')); // false,判断に失敗した
失敗は、 $ userオブジェクトがmyApp \ models \ userに属し、 「ユーザー」がグローバルネームスペースのユーザーであり、2つが一致しないことです。
それを書く正しい方法は、クラス全体の名前を渡すことです。
var_dump(is_a($user, 'MyApp\Models\User')); // true
または、使用する方が安全です::クラス定数:
var_dump(is_a($user, \MyApp\Models\User::class)); // true
クラス名が動的に渡された場合は、それが完全なクラス名であることを確認するか、現在の名前空間にスプライスします。
$class = 'User';
var_dump(is_a($user, __NAMESPACE__ . '\\' . $class)); // true
is_a() 3番目のパラメーター$ aopt_stringを使用すると、最初のパラメーターがオブジェクトでなければならないことを要求することなく、着信クラス名文字列を判断できます。
var_dump(is_a('MyApp\Models\User', 'MyApp\Models\User', true)); // true
現時点では、クラス名も完全であることを保証する必要があります。
名前空間はクラスのクラス名全体の名前を変更し、 IS_a()が判断されたときに渡さなければならないクラス名全体になります。
通常、名前空間のないクラス名を渡すと、判断が失敗します。
::クラス定数またはフル文字列を使用することが最も推奨される方法です。
動的なクラス名を判断するときに、名前空間の完成に注意してください。
これをマスターすると、PHPの名前空間によって引き起こされるタイプの判断トラップを効果的に回避し、コードの堅牢性と保守性を向上させることができます。