PHP에서 IS_A 함수는 객체가 클래스의 인스턴스인지 하위 클래스인지 여부를 결정하는 데 사용됩니다. 유형 감지에 매우 적합합니다. 그러나보다 유연하고 확장 가능한 유형의 판사를 작성하려면 폐쇄 (익명 함수)를 결합하여 동적 판단 논리를 구현하여 복제 된 IF 또는 스위치 명령문을 작성하지 않아도됩니다.
폐쇄와 결합 된 IS_A 기능을 사용하여 유연한 유형 판사를 작성하는 방법을 단계별로 살펴 보겠습니다.
<?php
class Animal {}
class Dog extends Animal {}
$dog = new Dog();
var_dump(is_a($dog, 'Dog')); // bool(true)
var_dump(is_a($dog, 'Animal')); // bool(true)
var_dump(is_a($dog, 'Cat')); // bool(false)
?>
IS_A는 객체가 특정 클래스 또는 하위 클래스의 인스턴스인지 판단 할 수 있으며, 이는 유형을 판단 할 기초를 제공합니다.
우리는 폐쇄를 사용하여 다른 판단 규칙을 정의한 다음 통합 인터페이스로 호출 할 수 있습니다.
<?php
$typeCheckers = [
'dog' => function($obj) {
return is_a($obj, 'Dog');
},
'animal' => function($obj) {
return is_a($obj, 'Animal');
},
'string' => function($obj) {
return is_string($obj);
}
];
// 사용의 예
function checkType($obj, $type, $checkers) {
if (!isset($checkers[$type])) {
throw new InvalidArgumentException("알 수없는 유형: $type");
}
return $checkers[$type]($obj);
}
$dog = new Dog();
var_dump(checkType($dog, 'dog', $typeCheckers)); // bool(true)
var_dump(checkType($dog, 'animal', $typeCheckers)); // bool(true)
var_dump(checkType("hello", 'string', $typeCheckers));// bool(true)
?>
이런 식으로 새로운 유형의 판단을 추가하려면 $ typecheckers 어레이에 폐쇄를 추가하면 코드의 유연성이 크게 향상되면됩니다.
때때로 우리는 클래스 이름을 기반으로 판사를 동적으로 만들어야하며, 우리는 신속하게 폐쇄를 생성하는 데 도움이되는 기능을 작성할 수 있습니다.
<?php
function makeIsATypeChecker(string $className) {
return function($obj) use ($className) {
return is_a($obj, $className);
};
}
$typeCheckers['cat'] = makeIsATypeChecker('Cat');
// 시험
class Cat extends Animal {}
$cat = new Cat();
var_dump(checkType($cat, 'cat', $typeCheckers)); // bool(true)
?>
이것은 우리의 유형 판사 시스템을보다 다재다능하고 유지하기 쉽게 만듭니다.
때로는 객체가 특정 인터페이스를 구현하는지 또는 특정 부모 클래스를 상속하는지 여부를 결정해야하며보다 일반적인 판사를 쓸 수 있습니다.
<?php
function makeClassOrInterfaceChecker(string $name) {
return function($obj) use ($name) {
return is_a($obj, $name) || in_array($name, class_implements($obj));
};
}
interface Pet {}
class Dog extends Animal implements Pet {}
$typeCheckers['pet'] = makeClassOrInterfaceChecker('Pet');
$dog = new Dog();
var_dump(checkType($dog, 'pet', $typeCheckers)); // bool(true)
?>
이런 식으로, 상속 관계와 인터페이스 구현을 모두 판단하는 것은 매우 유연합니다.
<?php
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
interface Pet {}
class DogPet extends Dog implements Pet {}
function checkType($obj, $type, $checkers) {
if (!isset($checkers[$type])) {
throw new InvalidArgumentException("알 수없는 유형: $type");
}
return $checkers[$type]($obj);
}
function makeIsATypeChecker(string $className) {
return function($obj) use ($className) {
return is_a($obj, $className);
};
}
function makeClassOrInterfaceChecker(string $name) {
return function($obj) use ($name) {
return is_a($obj, $name) || in_array($name, class_implements($obj));
};
}
$typeCheckers = [
'dog' => makeIsATypeChecker('Dog'),
'animal' => makeIsATypeChecker('Animal'),
'pet' => makeClassOrInterfaceChecker('Pet'),
'string' => function($obj) { return is_string($obj); },
];
// 시험
$dog = new Dog();
$cat = new Cat();
$dogPet = new DogPet();
var_dump(checkType($dog, 'dog', $typeCheckers)); // true
var_dump(checkType($cat, 'animal', $typeCheckers)); // true
var_dump(checkType($dogPet, 'pet', $typeCheckers)); // true
var_dump(checkType("hello", 'string', $typeCheckers));// true
?>
이런 식으로, 다양한 복잡한 비즈니스 요구에 대해 유연하고 확장 가능한 유형의 판사를 쉽게 구축 할 수 있습니다.