미운오리스키 님 박달나무 님 께 바칩니다. 정보
미운오리스키 님 박달나무 님 께 바칩니다.본문
어제 코드는 유익하였습니다. 저 나름대로도 무슨 코드일까 하고 봤다가 오버로딩인가 오버라이딩인가 (사실 큰 의미는 없습니다만) 하고 생각도 해보고 나름대로 오버로딩 오버라이딩 이야기도 하면서 다시 한번 찾아보게 되는
저에게도 매우 유익한 시간이였습니다.
제가 아는게 틀렸을까봐 더 많이 공부하게 해주기도 하였네요.
어제 제가 링크 올려두고 세부적으로 설명을 안한 부분에 대해 무언가 의견을 공유하고 배워가고 싶은 마음에
불러봅니다.
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 으로 메소드 오버로딩을 한건 또 아닌가 하고 생각해봅니다.
(사실 코드를 안봤으니 모르겠지만 추측이라는 점에서)
한동안 잊고 있었는데 다시 정리한걸 찾아보게 해주셔서 감사합니다.
추천
0
0
댓글 33개
아 적고나서 보니 카멜케이스 안되있네요 저도 블로그 같은곳에 올리면서 따로 정리 안하고 올렸던걸로 기억합니다. 코드의 오타보다는 내용만 봐주세요

눈이 피곤해 합니다..
오래 전에 클래스로 치장된 PHP게시판을 본 적이 있는데 그 후 신경을 안쓰고 있었거든요...
다시 보게 되니 공부는 해야겠다는 생각이 듭니다.
어제 온라인으로 PHP책을 검색해보니 대부분 초보자용 책들만 즐비한 것 같더라구요..
주말에 서점에 직접 나가 봐야겠습니다..
오래 전에 클래스로 치장된 PHP게시판을 본 적이 있는데 그 후 신경을 안쓰고 있었거든요...
다시 보게 되니 공부는 해야겠다는 생각이 듭니다.
어제 온라인으로 PHP책을 검색해보니 대부분 초보자용 책들만 즐비한 것 같더라구요..
주말에 서점에 직접 나가 봐야겠습니다..
결론만 딱 띄어서 보자면
어제의 그 코드가
people::peopleName('John', 'Tom', 'Bob'); 이것과 유사하지 않았나 하는 말입니다.
어제의 그 코드가
people::peopleName('John', 'Tom', 'Bob'); 이것과 유사하지 않았나 하는 말입니다.

그런 것 같아요..
:: 자체가 처음 만나는 것이어서...ㅎㅎ
:: 자체가 처음 만나는 것이어서...ㅎㅎ

클래스의 static 메소드를 불러올때 많이 사용합니다.

나린위키 http://narinwiki.org 프로그램 만들 떄, 이 __call 메소드란걸 알고 헉! 했었던 기억이 나네요
"아 뭐 이런.. 유들유들한 프로그래밍 랭귀지 같으니라고" 하면서 ㅎㅎㅎ
__call 함수도 그렇고 call_user_function_array 도 그렇고.. 참 .. 편리합니다 ㅎ
"아 뭐 이런.. 유들유들한 프로그래밍 랭귀지 같으니라고" 하면서 ㅎㅎㅎ
__call 함수도 그렇고 call_user_function_array 도 그렇고.. 참 .. 편리합니다 ㅎ
저도 매직매소드 참 좋아 합니다. getter setter 만 가지도고 object 운용에 편의를 느끼니까요.
근데 __call 이 많이 들어가는 코드가 된다면 오히려 별도의 자식 클래스를 생성해서
만들어가는 방식이 더 좋아보입니다.
core CLASS 를 하나 만들고 각 기능별 CLASS 에서 extends 해서 사용하는 방식이요
근데 __call 이 많이 들어가는 코드가 된다면 오히려 별도의 자식 클래스를 생성해서
만들어가는 방식이 더 좋아보입니다.
core CLASS 를 하나 만들고 각 기능별 CLASS 에서 extends 해서 사용하는 방식이요

넵 그게 정석이 아닐까 싶네요. __call 함수가 있으면.. 이게.. 분석하기가 참 난해할 수 있으니까요. 그때그때 상황에 따라 달라질수 있어서 좋기도 하면서, 오류나면 난감할 수 도 있고.. 다른사람이 보면 헉! 할수도 있는 ^^;

제가 지금 헉!하고 있습니다..ㅎ

저도 어제 좀 보니까 간단하게 아래같은 방식으로 처리해도
인자갯수라던가 타입별 처리까지는 가능은 하겠더라구요..
근데 기본적으로 지원되는게 아니라 약간 편법에 가까운...;
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 함수처럼 쓰면 될듯 하구요..
인자갯수라던가 타입별 처리까지는 가능은 하겠더라구요..
근데 기본적으로 지원되는게 아니라 약간 편법에 가까운...;
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 에서 가져다 써도 될거 같네요
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');
?>
요론식으로 ^^.. 재밌네요
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');
?>
요론식으로 ^^.. 재밌네요

요런 방식도 괜찮겠네요.. 인자 갯수별로 자동으로 해당함수 호출해서 ㅎㅎ
근데 그래도 어차피 노가다를 ㅠㅠ
근데 그래도 어차피 노가다를 ㅠㅠ

어차피 test1 함수만 추가된거니,
그렇게 노가다는 아니지 않을까요? ㅎㅎ 그래도 야메 오버로딩
---------
.. 타입까지 구분하려면.. 함수명이 지저분해지겠네요;;
그렇게 노가다는 아니지 않을까요? ㅎㅎ 그래도 야메 오버로딩
---------
.. 타입까지 구분하려면.. 함수명이 지저분해지겠네요;;

타입이 뭐뭐 있나 궁금해서 대충 테스트 해봤는데 생각보다 많네요 ㅎㅎ
참고로 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);
참고로 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);

----
요롷게 해볼 수 있겠는데... gettype 함수 반환값에 float 이 없어서 미운오리스키님 말씀처럼 float 으로는 안되네요 (뭔가 퀴즈 푸는 느낌 ㅎㅎ)
----
설명 부연하면
t() 함수에 파라미터를 넘기면 파라미터들의 타입의 첫 글자들로 _t_타입들() 함수를 호출하게 해봤는데.. 다행히 gettype 함수의 리턴값의 첫 글자들이 다 다르네요 ㅎㅎ
<?
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');
?>
요롷게 해볼 수 있겠는데... gettype 함수 반환값에 float 이 없어서 미운오리스키님 말씀처럼 float 으로는 안되네요 (뭔가 퀴즈 푸는 느낌 ㅎㅎ)
----
설명 부연하면
t() 함수에 파라미터를 넘기면 파라미터들의 타입의 첫 글자들로 _t_타입들() 함수를 호출하게 해봤는데.. 다행히 gettype 함수의 리턴값의 첫 글자들이 다 다르네요 ㅎㅎ

뭔가 잘(?) 처리하면 타입구분도 다 가능할듯 한데요 ㅎㅎ
타입명은 영어만드신분이 잘 만들어 놓으신듯 ㅋㅋ
float 는 찾아보니 is_float 라는 함수가 있네요..
결과값은 double 로...
걍 찍어보니 소수도 걍 double로 체크하면 된다는..
타입명은 영어만드신분이 잘 만들어 놓으신듯 ㅋㅋ
float 는 찾아보니 is_float 라는 함수가 있네요..
결과값은 double 로...
걍 찍어보니 소수도 걍 double로 체크하면 된다는..

좋은대요....^-^....

이거 괜찮은 흐름인데요..ㅎㅎ
http://php.net/manual/kr/language.references.whatdo.php
참조도 이용하면 조금 더 나아질려나요?
참조도 이용하면 조금 더 나아질려나요?

요건 포인터 개념이랑 비슷한건가요?
잘 쓰면 뭔가 나올것 같기도 한데 어케 써야할지를 ㅎㅎ
잘 쓰면 뭔가 나올것 같기도 한데 어케 써야할지를 ㅎㅎ
타입만 가지고 보면 int string boolean double float 등등 엄청 많지요

모죠? 이 어려운 것은 .. ㅡㅡ;;

가오가이거님을 스카웃하면 뭔가 큰 것을 만들 것 같은데...
스카웃할 능력이 없어요...ㅎㅎ
스카웃할 능력이 없어요...ㅎㅎ
전 지금 다니는 회사에 만족합니다 ㅎㅎ

그러니까요...
그래서 제가 스카웃 능력이 더 없는거죠..ㅎㅎ
그래서 제가 스카웃 능력이 더 없는거죠..ㅎㅎ
생각해보니 return 이니 else if 가 필요 없어서 또 바꿨습니다.
<?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;
<?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;
위의 코드에서 저 parame 체크 하는 부분 별도로 빼고 하면 깔끔해질거 같긴 한데 전 여기까지만 할께요 ㅎㅎ

네.. 나중에 유용하게 쓰일 소스들이 생긴것 같아서 뿌듯하네요 ㅎㅎ
수고하셨습니다~
수고하셨습니다~

저한테 밥사세요..ㅎㅎ