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

한빛출판네트워크

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

IT/모바일

PHP 참조(PHP References)

한빛미디어

|

2002-08-27

|

by HANBIT

11,894

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

이번 기사에서 여러분을 다시 만난 걸 환영한다. 지난번 기사에서는 PHP에서 객체(objects)를 사용하는 것에 대해 얘기하였다. 이번 기사에서는 조금은 어렵게 보일지도 모르는 PHP 참조(reference)에 대해 알아보고자 한다. C 프로그래밍을 해본 적이 있는 사람이라면 PHP에서의 참조가 C 스타일의 포인터와 같은 역할을 한다는 것을 알고 있을 것이다(물론 근본적으로는 다름). 물론 C를 모른다고 해서 걱정할 필요는 없다. 본 기사에서 여러분이 알아야 할 모든 것을 다룰 것이기 떄문이다.

참조의 기초

프로그래밍 경험과는 상관없이 PHP에서 참조의 개념은 아주 잘 된 설명을 듣지 않는 한 이해하기 어렵다. 앞에서도 말했듯이 PHP에서의 참조는 C 스타일 언어에서의 메모리 포인터와 같은 역할을 한다. C 스타일 언어에 익숙하지 않은 사람들을 위해 좀더 자세히 알아보도록 하겠다.

PHP에서 참조라는 것은 그 이름 자체의 의미에서 알 수 있듯이 다른 변수의 내용을 "가리키는" 변수이다. 예를 들어 다음의 짧은 코드를 보도록 하자.
";
        $foo++;
        $bar--;
    }
?>
위의 코드를 실행하면 결과는 어떻게 될까? 반목문을 5번 수행하면서 다음과 같은 출력 결과를 낸다는 것을 쉽게 알 수 있다.
The value of foo is: 5, and the value of bar is 5
The value of foo is: 6, and the value of bar is 4
....
The value of foo is: 10, and the value of bar is: 0
여기서 중요한 점은 변수 $foo$bar가 서로 독립적이라는 점이다. 그래서 변수 각각이 수정된다고 하더라도 다른 변수에 영향을 주지 않는다. PHP에서 참조는 개별적인 두 개의 변수를 하나처럼 사용할 수 있게 한다. 따라서 동시에 두개의 변수를 수정할 수 있다. 위의 코드에서 약간 변경된 다음의 코드를 살펴보도록 하자.
";
        $foo++;
        $bar--;
    }
?>
위의 코드에서 두 번째 줄이 변경되었음을 주목하기 바란다. $foo의 값을 단순히 $bar에 대입하는 대신, $bar$foo를 가리키도록 =& 연산자를 사용한 것이다. 차이가 무엇일까? 위의 코드가 수행된 결과를 살펴보자.
The value of foo is: 5, and the value of bar is: 5
The value of foo is: 5, and the value of bar is: 5
....
The value of foo is: 5, and the value of bar is: 5
보다시피 두 변수 모두 초기값에서 변경되지 않았다. 처음에는 이것이 버그처럼 보인다고 해도 일단은 코드를 자세히 살펴보도록 하자. 첫 라인에서 변수 $foo에 5라는 정수값을 대입하였다. 다음에 $foo를 가리키는 참조를 만들고 그것을 $bar라 지정하였다. for 루프에서는 두 변수를 출력하였고 처음에는 예상한 것처럼 두 변수 값이 모두 5로 출력된다. 그 다음 $foo의 값을 1 증가시키고, $bar의 값을 1 감소시켰다. 이 과정이 반복된다. 그런데 $foo$bar의 값이 왜 변하지 않을까?

처음 예제에서는 5라는 값을 $foo에 대입했다. 그런 후, $ba라는 변수를 생성하고 $foo와 같은 값을 대입하였다. 하지만 여기서는 두 번째 변수인 $bar가 생성되었고, 그래서 처음 변수와는 완전히 독립적이라는 점에 주목하기 바란다. 반면 두 번째 예제에서는 $foo를 가리키는 $bar라는 참조를 생성하였다. 이 경우에서는 두 번째 변수가 생성되지 않고, 하나의 변수에 두 가지 이름이 붙여진 것과 같다는 점에 주목해야 한다. 아래 그림을 보자.


[그림 1] 독립적인 변수로서의 $foo$bar


[그림 2] 변수 $foo를 가리키는 참조로서의 $bar

그림에서 보듯이 PHP에서 참조는 다른 이름을 사용하여 같은 물리적인 데이터를 다룰 수 있게 해준다. 두 번째 예제를 다시 한번 살펴보도록 하자. $foo가 1 증가했을 때 그 값이 6이 되는 것을 알 수 있다. 하지만 $bar$foo를 참조하고 있기 때문에 다음 라인에서 1이 감소하면 $foo는 다시 5의 값을 갖게 되는 것이다. 따라서 두 변수의 값이 전혀 바뀌지 않는 것처럼 보이는 것이다.


Programming PHP

참고 도서

Programming PHP
Kevin Tatroe, Rasmus Lerdorf




참조와 배열

보통 다른 변수들처럼, 참조도 배열로 선언될 수 있다. PHP에서 참조는 전체 배열을 가리킬 수도 있고, 배열의 특정 인덱스를 가리킬 수도 있다는 말이다. 아래의 예제를 살펴보자. 이는 각각 다른 배열을 가리키는 3개의 참조를 만든 것이다.
"variable1", 1=>"variable2", 2=>"variable3");
    $ref1 = &myarray;       // Reference the entire Array
    $ref2 = &myarray[0];    // Reference to the first index
    $ref3 = &myarray[1];    // Reference to the second index
?>
참조를 이용한 값 전달

참조는 위에서처럼 보통의 변수와 함께 사용되는 것 뿐만 아니라 함수의 파라미터로도 사용될 수 있다. 이는 하나의 함수에서 한 개 이상의 결과를 되돌려 줄 필요가 있을 때 특히 유용하다. 예를 들어 문자열을 두 개로 분리하는 split_string()이라는 함수를 만든다고 하자. 이 함수는 문자열과 정수로 이루어진 두 개의 파라미터를 갖고, 두 개의 문자열 조각을 리턴한다. 안타깝게도 함수에서는 기본적으로 두 개의 값을 리턴할 수 없다. 그래서 다른 방법이 필요하다. 첫번째 방법은 두 개의 분리된 문자열을 배열에 저장하여 배열을 리턴하는 것이고 두 번째 방법은 다음을 보면서 설명하겠다.

위의 방법에서 split_string() 함수는 2개가 아닌 4개의 파라미터를 갖는다. 처음 두 개의 파라미터는 위에서 이미 설명했다. 나머지 두 개의 파라미터는 결과가 저장될 변수를 참조하고 있는 것이다. 위 함수의 리턴값은 함수 동작의 성공여부를 나타내는 불린(Boolean) 값인 것을 살펴보기 바란다. 위 함수는 다음처럼 사용될 수 있다.
";
    }

    if(split_string($input_text, 10, &$first_half, &$second_half) == true) {
        echo "First segment of input: $first_half
"; echo "Second segment of input: $second_half
"; } ?>
이 코드의 출력은 다음과 같다.
Could not split input, cut-point is entire string!
First segment of input: abcdefghij
Second segment of input: klmnopqrstuvwxyz
위에서 보는 것처럼 함수가 참조를 파라미터로 사용했기 때문에 손쉽게 두 개의 리턴값을 얻을 수 있게 됐고, 함수의 리턴값을 에러 검사에 사용할 수 있게 됐다. 파라미터로 참조를 사용하는 것이 항상 좋은 것은 아니지만 이는 개발자에게는 많은 유연성을 제공해준다(특히 고급 알고리즘을 디자인할 때).

고급 참조

지금까지 참조에 대해 알아보았다. 다음 기사에서는 참조를 좀더 고급스럽게 사용하는 것에 대해 알아볼 것이다. 특히 객체에서 참조가 어떻게 구현되는 지를 알아 보고, 함수의 return 문을 이용해서 직접적으로 참조를 되돌려 주는 방법에 대해 알아볼 것이다.
존 코겐셀(John Coggeshall)은 10년이 넘게 개발을 해왔으며 PHP로는 5년 정도의 개발 경력을 가진 사설 웹 컨설턴트, 그래픽 디자이너이다.
TAG :
댓글 입력
자료실

최근 본 상품0