메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

PHP 레퍼런스 고급편

한빛미디어

|

2002-10-11

|

by HANBIT

12,335

저자: 존 코겐셀(John Coggeshall), 역 이호재

지난번 칼럼(PHP 참조)에서 필자는 기본적인 PHP 레퍼런스에 대한 설명과 그것을 어떻게 사용하는지에 대해 소개하였다. 이번 칼럼에서는 PHP에서 좀 더 난이도 있는 레퍼런스를 사용하는 방법에 대해 설명해보겠다. 따라서 본 기사에서는 함수에서 레퍼런스를 리턴하는 것과 관련된 개념 및 객체 내에서 레퍼런스를 사용하는 법을 다룰 것이다. 준비가 됐다면 이제 PHP 레퍼런스로의 여행을 떠나보자.

레퍼런스로 리턴하기

지난 칼럼에서는 PHP에서 여러 값을 리턴하기 위해 레퍼런스를 함수의 파라미터로 사용하는 방법에 대해 살펴보았다. 이번 칼럼에서는 레퍼런스를 실제 리턴값으로 사용하는 것에 대해 알아보고 이것이 개발자에게 얼마나 유용한지를 알아 볼 것이다. 이번 기사를 위해 다음과 같은 클래스를 만들었다.
";
        }
    }
    class B {
        function printmsg() {
            echo "Class is B
"; } } $toolbox[] = new A(); $toolbox[] = new B(); ?>
위 코드에서 보다시피 A와 B라는 간단한 두 개의 클래스를 생성했다. 그리고 각각은 printmsg()라는 함수 하나만을 포함하고 있다. 그리고 나서, 각 클래스의 인스턴스를 생성했고 $toobox라는 배열에 저장을 하였다. 우선 위의 것은 넘어가고, 레퍼런스 함수를 통해 전달하는 것부터 알아보자. 여러 곳에서 레퍼런스 함수에 의한 리턴이 쓰일 수 있지만, 여기서 생성할 함수는 오직 하나의 파라미터(이번 경우엔 간단히 하기 위해 불린 값(boolean value)을 사용하였다.)만을 받아들이고, 아래처럼 위에서 생성한 객체중 하나를 가리키는 레퍼런스를 리턴한다.
printmsg();
    $anothertool =& selectObject(false);
    $anothertool->printmsg();
?>
그렇다면 우리가 만든 selectObject()란 함수는 정확히 어떤 역할을 하는가? 함수 선언을 살펴보면, 이 함수는 파라미터로 하나의 불린 변수(boolean parameter) $which를 사용하고 있다. 그런데 함수 이름 앞에 있는 &는 도대체 무엇일까? 이 기호는 이 함수가 완전한 변수 대신에 PHP 레퍼런스를 리턴한다는 것을 정의한다. 함수 내부의 코드를 살펴보면, 이 함수가 앞에서 이미 정의한 $toolbox 배열에 저장되어 있는 하나의 객체를 리턴하는 것을 알 수 있다. 즉, 파라미터 값에 따라 우리가 정의한 객체중의 하나의 레퍼런스를 리턴하는 것이다.

이제 실제 함수가 어떻게 사용되는지 살펴보도록 하자. 위에서 보았듯이 $tool 변수를 selectObject()가 리턴하는 값으로 초기화하였다. 변수 값을 할당함에 있어 표준 문법을 사용하지 않고 지난번 칼럼에서 소개한 레퍼런스 결합 문법(reference-binding syntax)을 사용했다는 것에 주목하기 바란다. selectObject()가 레퍼런스를 리턴하는 함수이기 때문에 $tool 변수를 레퍼런스 변수로 다루어야 하고 그래서 "=&" 문법을 사용하였다. 일단 적절하게 할당이 되었다면, $tool은 이제 $toolbox 배열의 첫번째 인덱스인 $toolbox[0]를 가리키고 있을 것이고, 이는 클래스 A의 인스턴스를 나타낸다. 같은 방법으로 $anothertool 변수에 클래스 B의 인스턴스를 가리키도록 하였다(여기서는 단순하게 파라미터로 true대신 false를 전달했음).

위에서 보인 예제가 그리 실용적으로 보이지 않더라도, 탐색 트리나 다른 복잡한 데이터 구조를 다룰 때에는 레퍼런스를 리턴하는 함수를 사용하는 것이 아주 유용하다. 왜냐하면 개발자는 데이터 구조를 검색하면서 자신이 필요로하는 정확한 데이터 조각의 레퍼런스를 리턴할 수 있기 때문이다.

객체 생성자로써의 레퍼런스

지금까지 레퍼런스에 관한 거의 모든 것을 다루었다. 이제는 레퍼런스에서 가장 이해하기 어려운 것에 대해 살펴볼 차례이다. 생성자 내에서 객체로의 레퍼런스가 바로 가장 이해하기 어려운 부분 중에 하나인데 다음 클래스를 살펴보면서 알아보기로 하겠다.
value = $val;
        }
        function printval() {
            echo "The value of this class is "{$this->value}" 
"; } function setval($val) { $this->value = $val; } } ?>
이 객체의 생성자에서 전역 변수인 $myref$this (PHP에서 정의되어 있는 객체 자신을 가리키는 레퍼런스)를 참조하고 있고, 멤버 변수인 $value가 파라미터 $value 값을 갖는 것에 대해 주목하라. 이 클래스의 인스턴스가 생성될 때, 이 인스턴스를 가리키고 있는 전역 변수 $myref도 또한 생성된다. 따라서 아래와 같은 코드가 실행된다고 하면,
printval();
    $myref->printval();
?>
다음과 같이 출력될 것이다.
The value of this class is "FooBar!"
The value of this class is "FooBar!"
만약 이 클래스의 인스턴스에서 멤버 변수를 변경하려 한다면 어떻게 될까? 우리가 지금까지 배운 바에 기초하면 $myvar->setval()이나 $myref->setval()를 통한 변경은 두 가지 모두 영향을 줄 것이다. 하지만, 아래와 같은 코드가 실행된다면,
setval("Changed the value from $myvar");
    $myvar->printval();
    $myref->printval();
?>
결과 값은 다음과 같을 것이다.
The value of this class is "Change the value from $myvar"
The value of this class is "FooBar!"
왜 둘 모두의 값이 바뀌지 않았을까? 답은 객체가 처음 생성될 때 있다. PHP 4에서는 new 구문이 기본적으로 레퍼런스를 리턴하지 않는다. 오히려 $myvar 오브젝트가 생성될 때, $myref 변수에 의해 참조되는 것과는 다른 복사본이 리턴된다. 두 개가 같은 객체의 서로 다른 인스턴스이기 때문에, 그들의 변수는 완전히 독립적인 것이다. 이것 말고 우리가 처음에 바랐던 동작을 원한다면, 다음과 같이 객체를 생성할 때 레퍼런스 결합 문법을 사용해야 한다.
printval();
    $myref->printval();
    $myvar->setval("Now it works");
    $myvar->printval();
    $myref->printval();
?>
그리고 출력은 다음과 같다.
The value of this class is "Foobar!"
The value of this class is "Foobar!"
The value of this class is "Now it works"
The value of this class is "Now it works"
오늘 기사의 정리

지금까지 PHP 레퍼런스에 대해 알아야 할 모든 것을 다루어 보았다. 여러분은 필자가 보여준 것을 토대로 PHP 스크립트에서 레퍼런스를 적절히 사용함으로써 길지 않고 빠르고 효율적으로 동작할 수 있는 코드를 작성할 수 있을 것이다. 다음 기사에서는 약간 주제를 달리하여 PHP 페이지가 웹 브라우저에서 좀더 인터랙티브하고 다이나믹하게 보일 수 있도록 하는 것에 대해 알아볼 것이다.
참고 자료

존 코겐셀(John Coggeshall)은 10년이 넘게 개발을 해왔으며 PHP로는 5년 정도의 개발 경력을 가진 웹 컨설턴트이자 그래픽 디자이너이다.
TAG :
댓글 입력
자료실

최근 본 상품0