개요
PHP에서 함수의 인수(argument)는 값으로 전달(pass by value)하거나 참조로 전달(pass by reference)할 수 있습니다. 기본적으로 실제 인수의 값은 함수 내부의 지역 변수인 형식 인수(formal argument)에 복사되어 전달됩니다. 따라서 함수 내부에서 이 변수들을 수정해도 원래 변수의 값은 변경되지 않습니다.
반면 인수를 참조로 전달하면 형식 인수는 원래 변수를 가리키는 참조가 되기 때문에, 함수 내부에서 값을 변경하면 그 변경 사항이 원본 변수에 그대로 반영됩니다. 이러한 참조 전달 방식은 전역 범위(global scope)의 데이터를 간접적으로 조작할 수 있게 해주며, 함수가 하나의 값만 반환할 수 있다는 제약을 우회하는 데에도 유용합니다.
값으로 전달 (Pass by Value)
다음 예제에서는 두 변수를 swap() 함수에 전달합니다. 함수 내부에서 교환(swap) 로직이 실행되지만, 값이 복사되어 전달되었기 때문에 호출 측의 원본 변수 값은 변하지 않습니다.
예제
<?php
function swap($arg1, $arg2){
echo "inside function before swapping: arg1=$arg1 arg2=$arg2\n";
$temp=$arg1;
$arg1=$arg2;
$arg2=$temp;
echo "inside function after swapping: arg1=$arg1 arg2=$arg2\n";
}
$arg1=10;
$arg2=20;
echo "before calling function : arg1=$arg1 arg2=$arg2\n";
swap($arg1, $arg2);
echo "after calling function : arg1=$arg1 arg2=$arg2\n";
?>실행 결과
이 예제는 다음과 같은 결과를 출력합니다.
before calling function : arg1=10 arg2=20 inside function before swapping: arg1=10 arg2=20 inside function after swapping: arg1=20 arg2=10 after calling function : arg1=10 arg2=20
함수 호출 후에도 arg1과 arg2의 값이 그대로 10과 20인 것을 확인할 수 있습니다. 즉, 함수 내부의 교환이 외부에 영향을 주지 못했습니다.
참조로 전달 (Pass by Reference)
인수를 참조로 받으려면 형식 인수로 사용되는 변수 앞에 &(앰퍼샌드) 기호를 붙여야 합니다. 이렇게 하면 함수를 호출할 때 사용된 변수에 대한 참조가 전달되므로, 함수 내부에서 수행한 교환 작업의 결과가 원본 변수에도 그대로 반영됩니다.
예제
<?php
function swap(&$arg1, &$arg2){
echo "inside function before swapping: arg1=$arg1 arg2=$arg2\n";
$temp=$arg1;
$arg1=$arg2;
$arg2=$temp;
echo "inside function after swapping: arg1=$arg1 arg2=$arg2\n";
}
$arg1=10;
$arg2=20;
echo "before calling function : arg1=$arg1 arg2=$arg2\n";
swap($arg1, $arg2);
echo "after calling function : arg1=$arg1 arg2=$arg2\n";
?>실행 결과
교환 결과가 다음과 같이 출력됩니다.
before calling function : arg1=10 arg2=20 inside function before swapping: arg1=10 arg2=20 inside function after swapping: arg1=20 arg2=10 after calling function : arg1=20 arg2=10
이번에는 함수 호출 후 원본 변수의 값이 20과 10으로 서로 바뀐 것을 볼 수 있습니다. 매개변수에 & 기호 하나만 추가했을 뿐인데 동작이 완전히 달라진 것입니다.
배열 요소와 참조
배열을 초기화할 때 개별 변수에 대한 참조를 배열 요소로 저장하는 것도 가능합니다. 이 경우 배열 요소를 수정하면 해당 변수의 값도 함께 변경됩니다.
예제
<?php $a = 10; $b = 20; $c=30; $arr = array(&$a, &$b, &$c); for ($i=0; $i<3; $i++) $arr[$i]++; echo "$a $b $c"; ?>
실행 결과
$a, $b, $c의 값도 함께 증가합니다.
11 21 31
함수에 배열을 참조로 전달하기
배열 자체를 함수에 참조로 전달하는 것도 가능합니다. 아래 예제에서는 함수 내부에서 배열의 각 요소에 10을 더하면, 원본 배열이 직접 수정됩니다.
예제
<?php
function arrfunction(&$arr){
for ($i=0;$i<5;$i++)
$arr[$i]=$arr[$i]+10;
}
$arr=[1,2,3,4,5];
arrfunction($arr);
foreach ($arr as $i)
echo $i . " ";
?>실행 결과
수정된 배열이 다음과 같이 표시됩니다.
11 12 13 14 15
객체(Object)와 참조
PHP에서 객체는 기본적으로 참조로 전달됩니다. 객체의 참조가 생성되면, 객체를 인수로 넘길 때 $this 형태로 참조가 함께 전달되며 이 역시 첫 번째 객체에 대한 참조입니다. 따라서 두 변수는 사실상 동일한 객체 인스턴스를 가리키게 됩니다.
예제
<?php
class test1{
private $name;
function getname(){
return $this->name;
}
function setname($name){
$this->name=$name;
}
}
$obj1=new test1();
$obj2=&$obj1;
$obj1->setname("Amar");
echo "name: " .$obj2->getname();
?>실행 결과
위 코드는 다음과 같은 결과를 출력합니다.
name: Amar
$obj1에 이름을 설정했지만 $obj2를 통해서도 동일한 값이 조회되는 것을 확인할 수 있습니다. 이는 두 변수가 같은 객체를 참조하고 있기 때문입니다.
정리
PHP의 참조 전달은 다음과 같은 상황에서 유용하게 활용됩니다.
- 함수 내부에서 원본 변수의 값을 직접 변경해야 할 때
- 대용량 배열이나 문자열을 복사하지 않고 효율적으로 처리할 때
- 함수가 여러 개의 결과값을 반환해야 할 때 (참조 매개변수 활용)
- 객체를 다룰 때 (객체는 기본적으로 참조처럼 동작)
단, 참조를 남용하면 코드의 흐름을 추적하기 어려워지고 예기치 않은 부작용(side effect)이 발생할 수 있으므로, 필요한 경우에만 신중하게 사용하는 것이 좋습니다.