PHP에서 IS_A () 함수는 종종 객체가 특정 클래스에 속하는지 또는 인터페이스를 구현하는지 여부를 결정하는 데 사용되지만 객체가 특정 특성을 사용하는지 여부를 결정하는 데 사용하면 결과가 기대치를 충족시키지 못한다는 것을 알게됩니다. 이 기사는이 문제의 근본 원인을 파고 몇 가지 가능한 해결책을 제공합니다.
IS_A () 함수는 객체가 지정된 클래스의 인스턴스인지 또는 클래스의 서브 클래스인지 확인하는 데 사용됩니다. 일반적인 사용법은 다음과 같습니다.
if (is_a($obj, 'SomeClass')) {
// $obj 예 SomeClass 또는 서브 클래스 인스턴스
}
IS_A () 함수의 기본 계층은 실제로 객체의 클래스 상속 체인 및 인터페이스 구현을 판단하는 것입니다.
특성은 PHP 5.4에 도입 된 코드 재사용 메커니즘으로 여러 클래스에서 코드 블록을 "복사"할 수 있습니다. 특성은 자연의 클래스 나 인터페이스가 아닙니다. 별도로 인스턴스화 할 수 없으며 상속 체인에 나타나지 않습니다.
간단한 예를 들어 봅시다 :
trait Logger {
public function log($msg) {
echo $msg;
}
}
class User {
use Logger;
}
사용자 클래스는 로거 특성을 사용하지만 로거는 클래스가 아니므로 객체의 상속 구조에 나타나지 않습니다.
IS_A ()는 객체를 결정하는 클래스 또는 인터페이스 관계이므로 특성은 클래스 또는 인터페이스가 아니기 때문에 IS_A ($ obj, 'logger')는 false를 반환합니다.
$user = new User();
var_dump(is_a($user, 'Logger')); // false
로거는 $ 사용자 객체에 대한 클래스 나 인터페이스가 아니며 상속 체인에 있지 않기 때문입니다.
IS_A () 로 특성을 판단하는 것은 불가능하기 때문에 일반적인 대안은 Class_uses () 함수와 결합 된 PHP의 반사 메커니즘을 사용하는 것입니다.
class_uses ()는 클래스가 사용하는 모든 특성 (상속 특성 포함)을 반환합니다.
if (in_array('Logger', class_uses($user))) {
echo "User 사용된 Logger trait";
}
그러나 class_uses () 는 기본적으로 현재 클래스가 직접 사용하는 특성 만 반환하며 부모 클래스가 사용하는 특성을 포함하지 않습니다. 모든 상위 클래스가 사용하는 특성을 가져와야하는 경우 사용자 정의 기능을 사용하여 재귀 적으로 검색 할 수 있습니다.
function class_uses_recursive($class) {
$traits = [];
do {
$traits = array_merge($traits, class_uses($class));
} while ($class = get_parent_class($class));
return array_unique($traits);
}
if (in_array('Logger', class_uses_recursive($user))) {
echo "User 사용된 Logger trait(부모 수업을 포함하여)";
}
<?php
trait Logger {
public function log($msg) {
echo $msg;
}
}
class Base {
use Logger;
}
class User extends Base {}
$user = new User();
// 사용 is_a 심판 trait 결과는입니다 false
var_dump(is_a($user, 'Logger')); // bool(false)
// 사용 class_uses_recursive 심판 trait
function class_uses_recursive($class) {
$traits = [];
do {
$traits = array_merge($traits, class_uses($class));
} while ($class = get_parent_class($class));
return array_unique($traits);
}
if (in_array('Logger', class_uses_recursive($user))) {
echo "User 사용된 Logger trait";
} else {
echo "User 没有사용 Logger trait";
}
특성은 클래스 나 인터페이스가 아니기 때문에 IS_A ()는 특성을 판단하는 데 사용할 수 없습니다.
특성이 사용되는지 여부를 결정하려면 class_uses () 함수를 사용할 수 있습니다.
상위 클래스가 사용하는 특성을 확인 해야하는 경우 모든 상위 클래스의 특성을 재귀 적으로 얻어야합니다.
이 방법은 간단하고 효율적이며 매일 사용하기에 적합합니다.
특성의 특성과 PHP 유형 시스템을 이해함으로써, 우리는 객체와 특성 사이의 관계를 판단하는 방법을 합리적으로 선택하고 IS_A () 의 오용으로 인한 논리적 오류를 피할 수 있습니다.