PHP: 클래스 매직메소드 __get(), __set() 문제

2012-11-26

전에 PHP 클래스 매직메소드 __get(), __set() 예제 코드를 올린 적이 있다.

매직메소드 __get, __set에 대해서는 크게 두가지 의견이 있는데, 하나는 OO를 해치기 때문에 getter, setter를 정의해서 사용하라는 것이고, 또다른 하나는 스크립트 언어의 특성이므로 적극 활용을 해야 한다는 것이다.

한동안 getter, setter를 정의해서 사용하다, PHP가 스크립트 언어라는 특성을 활용하는 것이 맞는 이야기인 것 같아 매직메소드를 쓰기 시작한 것이 얼마 전부터 사용하고 있다.

그러나 매직메소드는 getter, setter를 작성하는 수고스러움 이상으로 문제를 일으키고 있다. 앞으로 __get(), __set() 매직메소드는 특별한 일이 아닌 이상 사용하지 않을 것 같다.

일단 아래 소스 코드를 보자. 전에 올렸던 글의 예제다.

이 코드는 하나의 클래스에서 문제를 일으키지 않는다. 그러나 상속을 받은 경우 다르다.

실행을 시켜보면 __get() 메소드에서 MyFoobar 클래스 멤버 변수 $age를 찾지 못 하는 것을 에러 메시지로 확인 할 수 있다. 이렇게 된 것은 __get() 메소드가 Foobar 클래스 내에 존재하기 때문이다. 이를 해결하기 위해서는 __get(), __set() 메소드를 MyFoobar로 옮기면 되지만, 그런 경우 Foobar 클래스에 문제가 생길뿐더라 전혀 아름다운 모습이 아니기도 하다.

그나마 조금 절충을 해 볼 수 있는 방법이 멤버 변수들은 protected로 바꾸고 ReflectionProperty() 함수를 이용하는 것이다.

에러가 발생하지 않고 의도한대로 동작한다. 하지만 private으로 선언한 멤버 변수들은 protected로 선언해야 하는 문제가 있다. 이런 문제를 완전히 해결하기 위해서는 다른 언어들처럼 getter, setter를 제대로 정의하는 것이 나아 보인다.

처음 의도한대로 멤버 함수를 private으로 유지하면서 자식 클래스에서 부모의 멤버 변수를 접근하는데 아무런 문제가 생기지 않는다.

다만 멤버 변수가 많은 경우 일일히 getter, setter를 입력하는 것이 번거로우므로 snippet을 생성하는 스크립트나 에디터의 snippet 생성 기능을 적극적으로 활용해서 반복적인 작업 시간을 절약하는 것이 좋을 듯 하다. 간단한 클래스 코드를 생성 해주는 페이지(PHP-GSGen)도 있으니 이것을 사용해도 괜찮다.

4 Comments
Minu
2013-01-17 @ 3:42 오후

final로 상속을 막으면 되지않나요?

응답
    2013-06-29 @ 8:55 오전

    상속이 필요한 상황이었기 때문에 final은 쓸 수 었었을 것 같습니다. final을 이용해서 적절한 대안을 만들어 낼 수 있을지 한 번 고민 해 볼 필요는 있을 듯 합니다.

    응답
2014-03-21 @ 4:56 오후

__get, __set을 사용해 본적은 없는데,
저 용도로 사용하라고 나온것 같진 않습니다..

저 용도라면, array와 차이가 없고,
오히려 array가 더 편리한 상황이네요..

응답

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.


*