Menu
Coddy logo textTech

__get, __set, __isset, __unset

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 46번째.

PHP는 속성 접근을 가로채는 네 가지 매직 메서드인 __get(), __set(), __isset(), 그리고 __unset()을 제공합니다. 이 메서드들은 존재하지 않거나 접근할 수 없는 속성에 접근하려고 할 때 트리거됩니다.

__get() 메서드는 접근할 수 없는 속성을 읽을 때 호출되며, __set()은 속성에 값을 쓸 때 이를 처리합니다. 이를 통해 동적 속성을 생성하거나 속성에 접근할 때 로직을 추가할 수 있습니다:

<?php
class DynamicObject {
    private array $data = [];
    
    public function __get(string $name): mixed {
        return $this->data[$name] ?? null;
    }
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
}

$obj = new DynamicObject();
$obj->title = "Hello";
$obj->count = 42;
echo $obj->title . " - " . $obj->count;

출력:

Hello - 42

__isset() 메서드는 isset() 또는 empty()에 의해 트리거되며, __unset()unset() 함수에 응답합니다:

<?php
class DynamicObject {
    private array $data = [];
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
    
    public function __isset(string $name): bool {
        return isset($this->data[$name]);
    }
    
    public function __unset(string $name): void {
        unset($this->data[$name]);
    }
}

$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing";

출력:

exists

이 메서드들은 객체 지향 구조를 유지하면서 유연한 데이터 컨테이너를 생성하거나, 지연 로딩(lazy loading)을 구현하거나, 배열처럼 동작하는 객체를 구축하는 데 흔히 사용됩니다.

challenge icon

챌린지

쉬움

매직 메서드를 사용하여 설정을 동적으로 저장하는 유연한 구성 관리자(configuration manager)를 만들어 보겠습니다. 여러분의 클래스는 속성 접근을 가로채서 구성 값을 관리하고, 설정이 존재하는지 확인하며, 필요할 때 제거하는 작업을 수행합니다. 이 모든 과정은 각 속성을 명시적으로 정의하지 않고 이루어집니다.

코드는 두 개의 파일로 구성됩니다:

  • Config.php — 내부적으로 구성 값을 저장하기 위해 프라이빗 배열을 사용하는 Config 클래스를 생성합니다. 다음 네 가지 속성 매직 메서드를 모두 구현하세요:
    • __get($name) — 주어진 키에 해당하는 값을 반환하거나, 키가 존재하지 않으면 "undefined"를 반환합니다.
    • __set($name, $value) — 주어진 키 아래에 값을 저장합니다.
    • __isset($name) — 구성에 해당 키가 존재하는지 여부를 반환합니다.
    • __unset($name) — 구성에서 해당 키를 제거합니다.
    또한 저장된 설정의 개수를 반환하는 count() 메서드를 추가하세요.
  • main.php — Config 파일을 포함합니다. 세 개의 입력(설정 이름, 설정 값, 그리고 두 번째 설정 이름)을 받게 됩니다. Config 인스턴스를 생성하고 다음 작업을 수행하세요:
    • 첫 번째 설정을 주어진 값으로 설정합니다.
    • isset()을 사용하여 첫 번째 설정이 존재하는지 여부를 출력합니다 — "exists" 또는 "missing"을 출력합니다.
    • 첫 번째 설정의 값을 출력합니다.
    • 현재 설정의 개수를 출력합니다.
    • unset()을 사용하여 첫 번째 설정을 제거합니다.
    • 이제 첫 번째 설정이 존재하는지 여부를 출력합니다 — "exists" 또는 "missing"을 출력합니다.
    • 두 번째 설정(한 번도 설정된 적 없는 설정)의 값을 출력합니다.

각 출력은 별도의 줄에 있어야 합니다. 매직 메서드를 사용하면 실제 속성이 정의되어 있지 않더라도 $config->theme = "dark"isset($config->theme)와 같은 자연스러운 속성 구문을 사용하여 Config 객체와 상호 작용할 수 있습니다.

치트 시트

PHP는 속성 접근을 가로채기 위한 네 가지 매직 메서드를 제공합니다:

  • __get(string $name): mixed — 접근할 수 없는 속성을 읽을 때 호출됨
  • __set(string $name, mixed $value): void — 접근할 수 없는 속성에 값을 쓸 때 호출됨
  • __isset(string $name): boolisset() 또는 empty()에 의해 트리거됨
  • __unset(string $name): voidunset()에 의해 트리거됨

__get()__set()의 예:

<?php
class DynamicObject {
    private array $data = [];
    
    public function __get(string $name): mixed {
        return $this->data[$name] ?? null;
    }
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
}

$obj = new DynamicObject();
$obj->title = "Hello";
echo $obj->title; // Hello

__isset()__unset()의 예:

<?php
class DynamicObject {
    private array $data = [];
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
    
    public function __isset(string $name): bool {
        return isset($this->data[$name]);
    }
    
    public function __unset(string $name): void {
        unset($this->data[$name]);
    }
}

$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing"; // exists

이 메서드들은 객체 지향 구조를 유지하면서 동적 속성, 지연 로딩(lazy loading) 및 유연한 데이터 컨테이너를 가능하게 합니다.

직접 해보기

<?php

require_once 'Config.php';

// 입력 읽기
$settingName1 = trim(fgets(STDIN));
$settingValue = trim(fgets(STDIN));
$settingName2 = trim(fgets(STDIN));

// TODO: Config 인스턴스 생성

// TODO: 첫 번째 설정을 주어진 값으로 설정

// TODO: 첫 번째 설정의 존재 여부 출력 ("exists" 또는 "missing")

// TODO: 첫 번째 설정의 값 출력

// TODO: 현재 설정의 개수 출력

// TODO: unset()을 사용하여 첫 번째 설정 제거

// TODO: 현재 첫 번째 설정의 존재 여부 출력 ("exists" 또는 "missing")

// TODO: 두 번째 설정의 값 출력 (설정된 적이 없음)

?>
quiz icon실력 점검

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

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