__call 및 __callStatic
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 47번째.
__get()과 __set()이 속성 접근을 가로채는 것처럼, __call()과 __callStatic() 메서드는 메서드 호출을 가로챕니다. 객체나 class에 존재하지 않거나 접근할 수 없는 메서드를 호출할 때 실행됩니다.
__call() 메서드는 인스턴스 메서드 호출을 처리합니다. 이 메서드는 메서드 이름과 인수 배열을 받습니다.
<?php
class Messenger {
public function __call(string $name, array $arguments): string {
return "Called '$name' with: " . implode(", ", $arguments);
}
}
$msg = new Messenger();
echo $msg->sendEmail("Hello", "World");
출력:
Called 'sendEmail' with: Hello, World정적 메서드 호출에는 __callStatic()을 사용하세요. static으로 선언해야 한다는 점에 유의하세요:
<?php
class QueryBuilder {
public static function __callStatic(string $name, array $arguments): string {
if (str_starts_with($name, "findBy")) {
$field = substr($name, 6);
return "Finding by $field: " . $arguments[0];
}
return "Unknown method: $name";
}
}
echo QueryBuilder::findByEmail("test@example.com");
출력:
Finding by Email: test@example.com이러한 magic 메서드는 fluent API를 만들거나, method 전달을 구현하거나, method 이름을 데이터베이스 작업으로 변환하는 dynamic 쿼리 빌더를 구축하는 데 강력하게 활용됩니다. 이를 통해 객체가 명시적으로 정의하지 않은 method를 포함하여 어떤 method 호출에도 지능적으로 응답할 수 있습니다.
챌린지
쉬움유연하게 method calls를 처리하기 위해 magic methods를 사용하는 dynamic API client를 만들어 봅시다. 각 method를 명시적으로 정의하지 않고도 instance 및 static method calls를 모두 가로채 의미 있는 API와 유사한 응답으로 변환하는 class를 만들 것입니다.
코드를 두 개의 파일로 구성합니다:
ApiClient.php: magic methods를 사용하여 API 상호 작용을 시뮬레이션하는ApiClientclass를 만듭니다. class에는 생성자를 통해 설정되는 private$baseUrlproperty가 있어야 합니다. 두 개의 magic methods를 Implement합니다:__call(): instance method calls를 처리합니다.get으로 시작하는 method(예:getUsers또는getPosts)가 호출되면 resource 이름("get" 뒤에 오는 부분)을 extract하고"GET [baseUrl]/[resource]: [arguments joined by comma]"을 반환합니다. resource 이름은 lowercase로 변환해야 합니다. method가 "get"으로 시작하지 않으면"Unknown action: [methodName]"을 반환합니다.__callStatic(): static method calls를 처리합니다.create로 시작하는 method(예:createUser)가 호출되면 resource 이름을 extract하고"POST /[resource]: [arguments joined by comma]"를 반환합니다. resource 이름은 lowercase여야 합니다.delete로 시작하는 methods에는"DELETE /[resource]: [first argument]"를 반환합니다. 그 밖의 모든 method에는"Static action not supported: [methodName]"을 반환합니다.
main.php: ApiClient 파일을 포함합니다. 세 개의 입력, 즉 base URL, resource 식별자, value를 받습니다. base URL을 사용하여ApiClientinstance를 만듭니다. 그런 다음 네 줄을 출력합니다:- resource 식별자를 method 이름의 접미사로 사용하여 dynamic
getmethod를 호출합니다(예: resource가 "Users"이면getUsers를 호출). value는 argument로 전달합니다. - 두 개의 arguments인
"electronics"와"active"를 사용하여getProducts를 호출합니다. - value를 argument로 사용하여 static method
createOrder를 호출합니다. - resource 식별자를 argument로 사용하여 static method
deleteItem을 호출합니다.
- resource 식별자를 method 이름의 접미사로 사용하여 dynamic
magic methods를 사용하면 API client가 모든 method call에 dynamic하게 응답할 수 있습니다. getUsers(), getPosts(), getProducts() 및 수십 개의 method를 각각 정의하는 대신, 하나의 __call() method가 method 이름을 검사하고 관련 정보를 extract하여 모두 처리합니다.
직접 해보기
<?php
require_once 'ApiClient.php';
// 입력 읽기
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: base URL로 ApiClient 인스턴스 생성
// TODO: resource를 메서드 이름 접미사로 사용하여 동적 get 메서드 호출
// Hint: $api->{"get" . $resource}($value)와 같은 변수 메서드 호출 사용
// TODO: "electronics"와 "active" 두 인수로 getProducts 호출
// TODO: value를 인수로 정적 메서드 createOrder 호출
// Hint: ApiClient::createOrder($value) 사용
// TODO: resource를 인수로 정적 메서드 deleteItem 호출
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러