Menu
Coddy logo textTech

__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 호출에도 지능적으로 응답할 수 있습니다.

challenge icon

챌린지

쉬움

유연하게 method calls를 처리하기 위해 magic methods를 사용하는 dynamic API client를 만들어 봅시다. 각 method를 명시적으로 정의하지 않고도 instance 및 static method calls를 모두 가로채 의미 있는 API와 유사한 응답으로 변환하는 class를 만들 것입니다.

코드를 두 개의 파일로 구성합니다:

  • ApiClient.php: magic methods를 사용하여 API 상호 작용을 시뮬레이션하는 ApiClient class를 만듭니다. class에는 생성자를 통해 설정되는 private $baseUrl property가 있어야 합니다. 두 개의 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을 사용하여 ApiClient instance를 만듭니다. 그런 다음 네 줄을 출력합니다:
    • resource 식별자를 method 이름의 접미사로 사용하여 dynamic get method를 호출합니다(예: resource가 "Users"이면 getUsers를 호출). value는 argument로 전달합니다.
    • 두 개의 arguments인 "electronics""active"를 사용하여 getProducts를 호출합니다.
    • value를 argument로 사용하여 static method createOrder를 호출합니다.
    • resource 식별자를 argument로 사용하여 static method deleteItem을 호출합니다.

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 호출

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 PHP 컴파일러