웹마스터 팁

자... 5번째 시간이 다가왔습니다.
이번에도 변수에 대한 부분을 할 건데요, 아무래도 프로그램의 기초라고 하면 변수와 함수가 되니까 열심히 해두는 것이 좋겠죠? 특히나 함수는 그때그때 알맞은 것을 골라서 쓰기만 하면 되지만, 변수에 대한 것은 한번 익혀두면 계속 어느 프로그램에서나 써먹는 거니까 꼭 익혀두는 것이 좋겠죠? ^^

저번에 얘기했던 글로벌 변수 즉, 전역변수와 이에 반대되는 지역변수의 개념을 익혀보도록 하겠습니다.
변수에 값을 할당할 때는 다음과 같이 합니다.

<?php
$a = 1;
?>

간단하죠? 그런데 이 $a 라는 값이 통하는 것은 어디까지일까요? 물론 프로그램 전체입니다.
그럼 다음의 예제를 보도록 하겠습니다.

<?php
$a = 1;

function test_Print(){
 echo $a;
}
?>

자... 위의 프로그램을 실행시키면 어떤 결과가 나올까요?
그전에 잠깐 살펴보자면, PHP언어의 구조중(이미 예전에 많이 보셨겠지만...) 함수는 다음과 같이 정의합니다.

function 함수명(전달변수){
 함수내용;
}

function 은 반드시 소문자로 지정해줘야 하는 것이며, 함수명은 영문자와 언더스코어(_), 그리고 숫자로만 구성됩니다. 단, 첫글자에는 숫자를 제외한 영문자나 언더스코어(_)만 올 수 있습니다. 다시 변수에 대한 얘기로 돌아가겠습니다. 저 소스를 실행시키면 결과가 어떻게 될까요? 아무런 일도 일어나지 않습니다. 함수는 정의를 해주는 것에서 끝나는 것이 아니라 그것을 호출시켜줘야 비로소 작동을 하게 됩니다. 즉, 다음과 같이 쓸 수 있는 것이죠.

<?php
$a = 1;

test_Print();

function test_Print(){
 echo $a;
}
?>

그럼 위의 소스를 실행하면 어떻게 될까요? ^^;; 역시 아무일도 일어나지 않습니다. 그 이유가 오늘 설명하려는 내용인데, 그게 바로 전역변수와 지역변수의 차이입니다. 전역변수로 지정한 변수는 함수안에서는 아무런 효력이 없습니다. 즉, function 바깥의 $a 와 function 안쪽의 $a는 생긴 것만 같지 전혀 다른 놈이라는 말이죠. "그 놈이 그 놈"처럼 만들려면 global 선언을 해주면됩니다.

<?php
$a = 1;

test_Print(); //test_Print 함수를 호출합니다.

function test_Print(){
 global $a; //이것으로 전역변수 $a를 함수안으로 불러들입니다.
 echo $a; //$a = 1 이 적용됩니다.
}
?>

간단하죠? 이것이 전역변수와 지역변수의 차이입니다. global 로 전역변수를 함수 안으로 불러오지 않으면 모양이 같아도 서로 다른 녀석들이 되어버린다는 것이죠. 다음의 결과도 재미있습니다.

<?php
$a = 1;

test_Print(); //test_Print 함수를 호출합니다.
echo $a; //$a의 값은?

function test_Print(){
 global $a; //이것으로 전역변수 $a를 함수안으로 불러들입니다.
 echo $a; //$a = 1 이 적용됩니다.
 $a = $a + 10; //$a에 10을 더합니다.
}
?>

5번째 줄의 $a의 값은 어떻게 될까요? 당연히 전역변수 자체를 변경시킨 것이므로 $a의 값은 1 + 10 = 11이 됩니다. 이제 전역변수와 지역변수에 대한 이해가 되시죠? 그럼 다시... ^^;; 혼자 공부하기에서는 다른 곳에서 잘하지 않는 걸 보여드립니다.

<?php
$a = 1;

test_Print(&$a);

function test_Print(&$var){
 echo $var;
}
?>

우선 특이한 기호가 하나 눈에 띄죠? 정식명칭은 ampersand(앰퍼샌드)라고 하지만 흔히 and(앤드)기호라고 많이 부르는(...나만 그런가... -_-;;) 기호가 있습니다. 프로그래밍 언어에서는 레퍼런스 연산자라고 부르는 건데, 개념을 깊이 파고들면 이해하기가 오히려 어려우니까 비교해서 보여드리겠습니다.

소스 1.
<?php
$a = 1;

test_Print($a);
echo $a;

function test_Print($var){
 $var = $var + 10;
}
?>

소스 2.
<?php
$a = 1;

test_Print(&$a);
echo $a;

function test_Print(&$var){
 $var = $var + 10;
}
?>

소스 1과 2의 차이는 단 한가지. &레퍼런스 연산자의 유무입니다. 그럼 각각 두 소스를 실행해보세요.

...................................................... 기다리는 중 ......................................................

대강 감이 오시나요? 우선 test_Print 라는 함수의 정의에서 괄호안에는 ($var)라는 값을 받아오도록 되어있습니다. 이 부분이 1과 2의 가장 큰 차이인데, 소스1의 보통의 사용법처럼 하면 $var 라는 변수에 $a 값을 "복사"하게 됩니다. 즉, $var 를 아무리 변화시켜도 원본인 $a에는 아무런 변화가 없다는 의미죠. 반면 레퍼런스 변수를 쓰면 $a 를 $var 라는 이름으로 끌어오게 됩니다. 원본 자체를 끌어와서 다루기 때문에 당연히 함수 바깥에서도 $a의 값은 바뀌어 있게 마련입니다. 사용법이 이해가 되시나요? 왜 이게 필요할까...라고 지금은 가물가물하시겠지만, 이 개념이 몹시 편리할 때가 있습니다. ^^;;

레퍼런스, 포인터라는 개념이 C라는 언어에 강력함이라는 마력을 부여했듯이 최근의 언어들은 이 개념을 거의 필수적으로 사용하고 있습니다. 물론, 그만큼 사용하기 어렵기도 하지만, 우리가 하는 PHP에서는 저 정도 개념만으로도 충분하니 나중에 다른 언어를 공부할 때 좀 더 확실하게 개념을 잡고 시작하세요. 그럼 다음 시간에는 연산자에 대해서 다루고 그 다음부터 응용편에 들어가도록 하겠습니다. 우선은 시간을 다루는 법부터 할 예정인데, 다른 원하시는 부분이 있으시면 말씀해주시기 바랍니다.

### 오늘 생각해볼 것.
숫자를 전달받으면 300을 곱해주는 함수를 작성하고 출력은 함수밖에서 할 것.