미운오리스키 님 박달나무 님 께 바칩니다.
어제 코드는 유익하였습니다. 저 나름대로도 무슨 코드일까 하고 봤다가 오버로딩인가 오버라이딩인가 (사실 큰 의미는 없습니다만) 하고 생각도 해보고 나름대로 오버로딩 오버라이딩 이야기도 하면서 다시 한번 찾아보게 되는
저에게도 매우 유익한 시간이였습니다.
제가 아는게 틀렸을까봐 더 많이 공부하게 해주기도 하였네요.
어제 제가 링크 올려두고 세부적으로 설명을 안한 부분에 대해 무언가 의견을 공유하고 배워가고 싶은 마음에
불러봅니다.
PHP 에는 매직매소드 라는 것이 존재합니다.
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(),
__isset(), __unset(), __sleep(), __wakeup(),
__toString(), __invoke(), __set_state() 그리고 __clone() 등등이 있지요.
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(),
__isset(), __unset(), __sleep(), __wakeup(),
__toString(), __invoke(), __set_state() 그리고 __clone() 등등이 있지요.
그 중 메소드 오버로딩으로 활용되는 __call() 이라는 부분과 __callStatic() 이라는부분이 있는데
제가 예전에 정리 해둔걸로는 다음과 같이 정의 해두었더라구요.
- __call()
- class 에서 정의 되지 않은 메서드에 접근을 할 때 자동 호출 되는 메소드 (메소드 오버로드)
- 앞쪽은 메소드 명이 오고, 뒤쪽은 넘어 오는 파라미터가 배열로 저장이 됨
- $params[0] 부터 접근을 할 수 있음
- 사용방법은 다음과 같음
<?php class people { public function __call($method, $params) { echo "Calling object method : " . $method . "<br />"; foreach ($params as $key => $value) { echo "name : " . $value . "<br />"; } } } $people = new people; $people -> peopleName('John', 'Tom', 'Bob'); ?> - 결과 : Calling object method : peopleName
name : John
name : Tom
name : Bob
- __callstatic()
- __call 과 같은 메소드 오버로딩
- _call 과 _callstatic 의 차이
- __call 은 object context 즉 클래스가 인스턴스화 되어 객체 상태로 존재할 때 호출 됨
- __callstatic 은 static context 즉 인스턴스화 되지 않는 상태에서 호출 됨
- 사용 방법은 다음과 같음
<?php class people { public function __callstatic($method, $params) { echo "Calling object method : " . $method . "<br />"; foreach ($params as $key => $value) { echo "name : " . $value . "<br />"; } } } people::peopleName('John', 'Tom', 'Bob'); ?> - 결과 (__call 과 동일) : Calling object method : peopleName
name : John
name : Tom
name : Bob
이걸 보면서 어제의 코드가 __callStatic 으로 메소드 오버로딩을 한건 또 아닌가 하고 생각해봅니다.
(사실 코드를 안봤으니 모르겠지만 추측이라는 점에서)
한동안 잊고 있었는데 다시 정리한걸 찾아보게 해주셔서 감사합니다.
|
댓글을 작성하시려면 로그인이 필요합니다.
로그인
댓글 33개
오래 전에 클래스로 치장된 PHP게시판을 본 적이 있는데 그 후 신경을 안쓰고 있었거든요...
다시 보게 되니 공부는 해야겠다는 생각이 듭니다.
어제 온라인으로 PHP책을 검색해보니 대부분 초보자용 책들만 즐비한 것 같더라구요..
주말에 서점에 직접 나가 봐야겠습니다..
어제의 그 코드가
people::peopleName('John', 'Tom', 'Bob'); 이것과 유사하지 않았나 하는 말입니다.
:: 자체가 처음 만나는 것이어서...ㅎㅎ
http://www.php.net/manual/kr/keyword.paamayim-nekudotayim.php
한글로는 범위지정연산자 라고 부릅니다.
"아 뭐 이런.. 유들유들한 프로그래밍 랭귀지 같으니라고" 하면서 ㅎㅎㅎ
__call 함수도 그렇고 call_user_function_array 도 그렇고.. 참 .. 편리합니다 ㅎ
근데 __call 이 많이 들어가는 코드가 된다면 오히려 별도의 자식 클래스를 생성해서
만들어가는 방식이 더 좋아보입니다.
core CLASS 를 하나 만들고 각 기능별 CLASS 에서 extends 해서 사용하는 방식이요
인자갯수라던가 타입별 처리까지는 가능은 하겠더라구요..
근데 기본적으로 지원되는게 아니라 약간 편법에 가까운...;
function test1(){
switch(func_num_args()){
case 1: echo("function1<br>"); break;
case 2: echo("function2<br>"); break;
case 3: echo("function3<br>"); break;
}
}
test1('1');
test1('1','2');
function test2(){
$a = gettype(func_get_arg(0));
if($a=='integer'){
echo("integer param<br>");
}else if($a=='string'){
echo("string param<br>");
}
}
test2(123);
test2('123');
test1 함수는 인자별 갯수에 따라 case 문으로 처리하면 될듯하고
변수타입에 따라 처리가 달라져야 한다면 test2 함수처럼 쓰면 될듯 하구요..
test1 같은 경우에는 별도로 function 빼두어서 다른 function 에서 가져다 써도 될거 같네요
좀 귀찮긴 해도 원하는 방식으로 대부분 처리는 가능하겠더라구요..
function test1() {
call_user_func_array('_t'.func_num_args(), func_get_args());
}
function _t1($arg) {
echo 'This is _t1() : ' . $arg . '<br/>';
}
function _t2($arg1, $arg2) {
echo 'This is _t2() : ' . $arg1 . ', ' . $arg2 . '<br/>';
}
test1('1');
test1('1','2');
?>
요론식으로 ^^.. 재밌네요
근데 그래도 어차피 노가다를 ㅠㅠ
그렇게 노가다는 아니지 않을까요? ㅎㅎ 그래도 야메 오버로딩
---------
.. 타입까지 구분하려면.. 함수명이 지저분해지겠네요;;
참고로 float 는 안되는듯 ㅠㅠ
function test2(){
$a = gettype(func_get_arg(0));
if($a=='integer'){
echo("integer param<br>");
}else if($a=='string'){
echo("string param<br>");
}else if($a=='boolean'){
echo("boolean param<br>");
}else if($a=='array'){
echo("array param<br>");
}else if($a=='float'){
echo("float param<br>");
}
}
test2(123);
test2('123');
test2(true);
test2(array('a'));
test2(0.5);
[code]
<?
function t(){
$types = implode('', array_map(create_function('$item', '$type = gettype($item); return $type{0};'), func_get_args()));
$func = '_t_'.$types;
if(function_exists($func)) return call_user_func_array($func, func_get_args());
echo('ERROR : function does not exist - '. $func.'<br/>');
}
function _t_d($double) { echo 'This is _t_d() : ' . $double. '<br/>'; }
function _t_s($str) { echo 'This is _t_s() : ' . $str. '<br/>'; }
function _t_i($num) { echo 'This is _t_i() : ' . $num. '<br/>'; }
function _t_si($str, $num) { echo 'This is _t_si() : ' . $str. ', '. $num . '<br/>'; }
function _t_ss($str1, $str2) { echo 'This is _t_ss() : ' . $str1. ', ' . $str2. '<br/>'; }
function _t_iss($num, $str1, $str2) { echo 'This is _t_iss() : ' . $num . ', ' . $str1. ', ' . $str2. '<br/>'; }
t(0.1);
t('1');
t(2);
t('3', 4);
t('5', '6');
t(7, '8', '9');
?>
[/code]
요롷게 해볼 수 있겠는데... gettype 함수 반환값에 float 이 없어서 미운오리스키님 말씀처럼 float 으로는 안되네요 (뭔가 퀴즈 푸는 느낌 ㅎㅎ)
----
설명 부연하면
t() 함수에 파라미터를 넘기면 파라미터들의 타입의 첫 글자들로 _t_타입들() 함수를 호출하게 해봤는데.. 다행히 gettype 함수의 리턴값의 첫 글자들이 다 다르네요 ㅎㅎ
타입명은 영어만드신분이 잘 만들어 놓으신듯 ㅋㅋ
float 는 찾아보니 is_float 라는 함수가 있네요..
결과값은 double 로...
걍 찍어보니 소수도 걍 double로 체크하면 된다는..
참조도 이용하면 조금 더 나아질려나요?
잘 쓰면 뭔가 나올것 같기도 한데 어케 써야할지를 ㅎㅎ
스카웃할 능력이 없어요...ㅎㅎ
그래서 제가 스카웃 능력이 더 없는거죠..ㅎㅎ
<?php
class TypeCheck
{
const PUSH_INT = 'integer';
const PUSH_STRING = 'string';
const PUSH_BOOLEAN = 'boolean';
const PUSH_ARRAY = 'array';
const PUSH_DOUBLE = 'double';
public function checkData($param)
{
$param = gettype(func_get_arg(0));
if ($param == TypeCheck::PUSH_INT) {
return "integer param<br>";
}
if ($param == TypeCheck::PUSH_STRING) {
return "string param<br>";
}
if ($param == TypeCheck::PUSH_BOOLEAN) {
return "boolean param<br>";
}
if ($param == TypeCheck::PUSH_ARRAY) {
return "array param<br>";
}
if ($param == TypeCheck::PUSH_DOUBLE) {
return "float param<br>";
}
}
}
$checkData = new TypeCheck();
$a = $checkData->checkData(11111);
$b = $checkData->checkData(1.5);
echo $a . $b;
수고하셨습니다~