Computer >> 컴퓨터 >  >> 프로그래밍 >> PHP

PHP에서 C++의 friend(친구) 선언을 흉내 내는 방법

PHP는 friend 또는 internal 접근 제어를 지원할까?

결론부터 말씀드리면, PHP는 C++의 friend나 C#의 internal처럼 특정 클래스에 한해 private 멤버 접근을 허용하는 선언을 공식적으로 지원하지 않습니다. 언어 차원에서 이러한 세밀한 접근 제어 문법이 없기 때문에, 개발자는 다른 우회 방법을 찾아야 합니다.

__get과 __set 매직 메서드로 friend 흉내 내기

PHP 5 이상에서는 __get()__set() 매직 메서드를 활용하고, debug_backtrace() 함수로 호출자의 클래스를 검사하는 방식으로 friend와 유사한 동작을 흉내 낼 수 있습니다. 아래 예제 코드를 살펴보겠습니다.

class sample_friend {
    private $__friends = array('My_Friend', 'Other_Friend');

    public function __get($key) {
        $trace = debug_backtrace();
        if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
            return $this->$key;
        }
        // 일반적인 __get() 처리 코드
        trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
    }

    public function __set($key, $value) {
        $trace = debug_backtrace();
        if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
            return $this->$key = $value;
        }
        // 일반적인 __set() 처리 코드
        trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
    }
}

동작 원리

  1. 허용할 클래스 이름을 $__friends 배열에 미리 정의해 둡니다.
  2. 외부에서 private 프로퍼티에 접근하려 하면 PHP가 자동으로 __get() 또는 __set()을 호출합니다.
  3. debug_backtrace()로 호출 스택을 확인하여, 실제 호출한 클래스가 허용 목록($__friends)에 있는지 검사합니다.
  4. 허용된 클래스라면 프로퍼티 접근을 그대로 반환하고, 그렇지 않으면 trigger_error()로 치명적 오류를 발생시켜 접근을 차단합니다.

주의할 점

이 방식은 동작은 하지만, 실무에서는 서투르고(clumsy) 권장되지 않는 코딩 관행으로 여겨집니다. 그 이유는 다음과 같습니다.

  • debug_backtrace() 호출은 성능 오버헤드가 상당히 큽니다.
  • friend 목록이 문자열로 하드코딩되어 유지보수가 어렵고, 클래스 리팩터링 시 깨지기 쉽습니다.
  • 코드의 의도가 명확하게 드러나지 않아 가독성이 떨어집니다.

따라서 실제 프로젝트에서는 이런 트릭보다는 인터페이스 설계, 컴포지션(위임), 팩토리 패턴 등 객체지향 원칙에 맞는 구조로 문제를 해결하는 것이 바람직합니다.