Computer >> 컴퓨터 >  >> 프로그래밍 >> PHP

PHP 참조(Reference)로 값 전달하기 – Pass by Value와 Pass by Reference 완벽 이해

개요

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)이 발생할 수 있으므로, 필요한 경우에만 신중하게 사용하는 것이 좋습니다.