PHP 클래스 캡슐화하기
컨텐츠 정보
- 17,808 조회
- 6 추천
- 목록
본문
class test
{
var $elem;
var $public_var = array('pub1','pub2','pub3');
var $public_method = array('method1');
function __get($key, &$val)
{
if (!in_array($key, $this->public_var)) {
// false를 반환해도 에러처리를 하지 않습니다.
// 에러처리를 하려면 이 부분에 입력하세요.
echo '`$'.$key.'` is not public property!';
return false;
} elseif (isset($this->elem[$key])) {
echo 2;
$val = $this->elem[$key];
return true;
} else {
echo 3;
return false;
}
}
function __set($key, $val) {
if (in_array($key, $this->public_var)) {
$this->elem[$key] = $val;
return true;
} else {
// 프로퍼티 셋은 false를 반환하면 에러처리를 합니다.
// 별도의 에러처리를 하고 싶으시면 이 부분에 입력하세요.
echo '`$'.$key.'` is Not public property!';
return false;
}
}
// FIXME : __call 에 대한 오버로드가 제대로 작동하지 않습니다.
// 잘 되다가 갑자기 안되는데, 이유는 모르겠습니다. ^^;;
function __call($method, $args, &$return)
{
if ($method == get_class(&$this)) {
return true;
} elseif (in_array($method, $this->public_method)) {
$return = call_user_method_array ( $method, &$this, $args);
return true;
} else {
// 퍼블릭 함수가 아닐때
return true;
}
}
function method1($str1, $str2) //public
{
echo 'method1->params = '.$str1.' glue '.$str2.'';
}
function method2($str1, $str2) //private
{
echo 'method2->params = '.$str1.' glue '.$str2.'';
}
}
overload('test');
$test = new test;
$test->pub1 = '111';
$test->method2('1', '2');
$test->method1('3', '4');
모양을 보면 대강 이해하실겁니다.
PHP의 클래스가 불완전한 이유중에 하나가 오버로드와 오버라이딩이 지원안된다는 거였는데(저는 그렇게 알고 있었습니다), 거기에 또 하나의 이유가 있다면 캡슐화가 안된다는 거죠. 클래스의 큰 특징중의 하나가 없으니 사실 PHP의 클래스는 클래스라기 보다는 함수모음이었죠.
오늘 우연히 overload 라는 함수를 보고 그 예제를 보게 되었는데, 정말 유용하게 쓸 수 있을 것 같아서 소개하려고 하다가 그 김에 캡슐화를 구현해보았습니다.
클래스 선언부에 var 로 선언한 프로퍼티들은 사실 외부에서 값을 변경해도 아무런 저항없이(?) 변경되어야 했지만, 클래스 내장메소드인 __get 과 __set 을 오버로드하면 충분히 캡슐화할 수 있습니다. 미리 공개 프로퍼티를 배열로 정해주고, 클래스 외부에서 요구하는 프로퍼티의 이름이 공개 프로퍼티가 아니면 에러처리를 하는 것입니다.
설명잘하는 능력이 없어서 길게 설명드리지는 못하지만, 예문도 함께 올렸으니 한번씩 테스트해보시면 재미있는 결과를 얻을 수 있을겁니다.
※ PHP 버전이 4.2.0 보다 높아야 하며, __call 메소드는 4.3.0 이후 가능. 4.3.0 이전에는 따로 옵션을 줘서(--enable-overload) 컴파일해야 사용가능하나, 4.3.0부터는 따로 옵션을 주지 않아도 포함되어 컴파일 된다.
P.S// 원래는 __call 도 오버로드하여 method 도 public과 private 를 구현하려 했는데, 주석에 쓴대로 이상하게 안 먹히더군요. ㅡ.ㅡ;; 그것도 잘 되다가 갑자기 __call 자체를 안 불러버리는 요상한 일이 발생하더군요. 쩝....
관련자료
-
링크
댓글 0
등록된 댓글이 없습니다.