코딩 스쿨 PHP

언어선택 : HTMLCSSJAVAJAVASCRIPTMYSQLSQL PHP

PHP Array

PHP Array Reference: 이해와 활용


  • *배열 참조(Array Reference)**는 PHP에서 배열을 다룰 때 매우 유용한 개념입니다. 배열 참조를 사용하면 배열을 복사하지 않고 원본 배열을 직접 참조할 수 있어 메모리 효율성을 높이고, 여러 변수나 함수에서 동일한 배열을 조작할 수 있습니다. 그러나 참조를 사용할 때는 주의가 필요하며, 올바르게 이해하고 사용해야 의도하지 않은 부작용을 방지할 수 있습니다.

이 가이드에서는 PHP 배열 참조의 개념부터 실제 활용 사례주의사항까지 상세히 설명합니다.


1. 배열 참조의 기본 개념

1.1 배열 복사 vs 배열 참조

  • 배열 복사(Copying Arrays):

    • 배열을 복사하면 새로운 배열이 생성되며, 원본 배열과 복사된 배열은 독립적으로 존재합니다.
    • 한 배열을 변경해도 다른 배열에는 영향을 주지 않습니다.
    <?php
    $original = array("Apple", "Banana", "Cherry");
    $copy = $original; // 배열 복사
    
    $copy[0] = "Orange";
    
    print_r($original); // 출력: Array ( [0] => Apple [1] => Banana [2] => Cherry )
    print_r($copy);     // 출력: Array ( [0] => Orange [1] => Banana [2] => Cherry )
    ?>
    
    
  • 배열 참조(Reference Arrays):

    • 배열 참조는 원본 배열을 참조하여 두 변수가 동일한 배열을 가리키도록 합니다.
    • 한 변수를 통해 배열을 변경하면, 다른 변수에서도 변경 사항이 동시에 반영됩니다.
    <?php
    $original = array("Apple", "Banana", "Cherry");
    $reference = &$original; // 배열 참조
    
    $reference[0] = "Orange";
    
    print_r($original);    // 출력: Array ( [0] => Orange [1] => Banana [2] => Cherry )
    print_r($reference);  // 출력: Array ( [0] => Orange [1] => Banana [2] => Cherry )
    ?>
    
    

2. 배열 참조와 함수

PHP에서 배열을 함수에 전달할 때, 참조로 전달하면 함수 내부에서 배열을 수정할 수 있습니다. 이를 통해 함수가 배열을 직접 변경하게 할 수 있으며, 메모리 사용을 최적화할 수 있습니다.

2.1 배열을 참조로 전달하기

<?php
function addFruit(&$arr, $fruit) {
    $arr[] = $fruit;
}

$fruits = array("Apple", "Banana");
addFruit($fruits, "Cherry");

print_r($fruits); // 출력: Array ( [0] => Apple [1] => Banana [2] => Cherry )
?>

설명:

  • 함수 addFruit는 배열 $arr를 참조로 전달받습니다 (&$arr).
  • 함수 내에서 배열에 요소를 추가하면, 원본 배열 $fruits도 변경됩니다.

2.2 배열을 참조로 반환하기

함수에서 배열을 참조로 반환하면, 반환된 변수를 통해 원본 배열을 수정할 수 있습니다.

<?php
function &getFruits() {
    $fruits = array("Apple", "Banana");
    return $fruits;
}

$refFruits = &getFruits(); // 참조로 반환받기
$refFruits[] = "Cherry";

print_r($refFruits); // 출력: Array ( [0] => Apple [1] => Banana [2] => Cherry )
?>

주의사항:

  • 참조로 반환된 배열은 함수가 종료된 후에도 참조가 유지되지 않을 수 있으므로, 실제로 유용하게 사용하기는 어렵습니다.
  • 대부분의 경우, 배열을 참조로 반환하는 것은 권장되지 않습니다.

3. 참조를 사용한 배열 요소 접근

배열의 각 요소를 참조로 접근하여 직접 수정할 수 있습니다. 이는 foreach 루프와 함께 자주 사용됩니다.

3.1 foreach 루프에서 참조 사용하기

<?php
$fruits = array("Apple", "Banana", "Cherry");

foreach ($fruits as &$fruit) {
    $fruit = strtoupper($fruit);
}
unset($fruit); // 참조 해제

print_r($fruits); // 출력: Array ( [0] => APPLE [1] => BANANA [2] => CHERRY )
?>

설명:

  • &$fruit를 사용하여 각 요소에 참조로 접근합니다.
  • 배열의 각 요소를 대문자로 변경합니다.
  • *unset($fruit)*을 사용하여 참조를 해제합니다. 이는 참조 변수가 루프 외부에서도 영향을 미치는 것을 방지합니다.

3.2 다차원 배열에서 참조 사용하기

<?php
$matrix = array(
    array(1, 2, 3),
    array(4, 5, 6),
    array(7, 8, 9)
);

foreach ($matrix as &$row) {
    foreach ($row as &$element) {
        $element *= 2;
    }
    unset($element); // 내부 참조 해제
}
unset($row); // 외부 참조 해제

print_r($matrix);
/* 출력:
Array
(
    [0] => Array ( [0] => 2 [1] => 4 [2] => 6 )
    [1] => Array ( [0] => 8 [1] => 10 [2] => 12 )
    [2] => Array ( [0] => 14 [1] => 16 [2] => 18 )
)
*/
?>

설명:

  • 다차원 배열에서 각 행과 각 요소를 참조로 접근하여 값을 수정합니다.
  • 내부 참조 ($element)와 외부 참조 ($row)를 모두 해제하여 의도하지 않은 참조를 방지합니다.

4. 참조의 주의사항

4.1 참조 해제

참조를 사용한 후에는 반드시 참조 변수를 해제해야 합니다. 그렇지 않으면 이후의 변수 할당이 참조에 영향을 미칠 수 있습니다.

<?php
$array1 = array("Apple", "Banana");
$array2 = &$array1;

$array2[] = "Cherry";

unset($array2); // 참조 해제

$array3 = "Orange";
$array1[] = $array3;

print_r($array1); // 출력: Array ( [0] => Apple [1] => Banana [2] => Cherry [3] => Orange )
?>

설명:

  • unset($array2)를 통해 $array2$array1 간의 참조를 해제합니다.
  • 이후 $array3$array1에 추가해도 참조가 적용되지 않습니다.

4.2 참조와 foreach 루프의 혼동

foreach 루프에서 참조를 사용한 후 참조 변수를 해제하지 않으면 의도치 않은 변수 변경이 발생할 수 있습니다.

<?php
$fruits = array("Apple", "Banana", "Cherry");

foreach ($fruits as &$fruit) {
    // ...
}
unset($fruit); // 참조 해제하지 않으면 아래와 같은 문제가 발생할 수 있음

$fruits[] = "Orange";

print_r($fruits);
/* 예기치 않은 출력:
Array
(
    [0] => Apple
    [1] => Banana
    [2] => Cherry
    [3] => Orange
)
*/
?>

해결책:

  • *반드시 unset()*을 사용하여 참조 변수를 해제합니다.
  • unset($fruit)를 통해 참조를 해제하면 이후의 배열 조작에 영향을 주지 않습니다.

5. 참조와 배열의 고급 활용

5.1 참조를 사용한 배열 요소 스왑

<?php
function swap(&$a, &$b) {
    $temp = $a;
    $a = $b;
    $b = $temp;
}

$array = array("first" => 1, "second" => 2);
swap($array["first"], $array["second"]);

print_r($array); // 출력: Array ( [first] => 2 [second] => 1 )
?>

설명:

  • 함수 swap참조를 통해 배열 요소를 직접 교환합니다.
  • 배열의 특정 요소를 참조로 전달하여 원본 배열을 직접 수정합니다.

5.2 참조를 사용한 배열 복사

<?php
$array1 = array("Apple", "Banana", "Cherry");
$array2 = &$array1; // 참조로 복사

$array2[1] = "Blueberry";

print_r($array1); // 출력: Array ( [0] => Apple [1] => Blueberry [2] => Cherry )
?>

설명:

  • $array2$array1참조하므로, $array2의 변경은 $array1에 직접적인 영향을 미칩니다.

6. 배열 참조의 장단점

장점 단점
메모리 효율성: 동일한 데이터를 여러 변수에서 참조할 때 메모리를 절약할 수 있습니다. 복잡성 증가: 참조를 남용하면 코드의 가독성이 떨어지고, 디버깅이 어려워질 수 있습니다.
데이터 일관성: 여러 참조 변수가 동일한 데이터를 가리키므로, 한 곳에서 데이터를 변경하면 모든 참조에 반영됩니다. 예기치 않은 변경: 참조 해제를 제대로 하지 않으면 의도치 않은 데이터 변경이 발생할 수 있습니다.
함수 내에서 배열을 직접 수정할 수 있어, 함수의 효율성을 높일 수 있습니다. 참조의 오용: 참조를 잘못 사용하면 코드의 동작을 예측하기 어려워질 수 있습니다.

7. Best Practices (최고의 실천 방법)

  1. 필요할 때만 참조 사용:
    • 배열 참조는 메모리 효율성이 필요하거나, 여러 변수에서 동일한 배열을 조작해야 할 때만 사용합니다.
  2. 참조 해제 잊지 않기:
    • 참조를 사용한 후에는 반드시 **unset()*을 통해 참조를 해제합니다.
  3. 명확한 코드 작성:
    • 참조를 사용할 때는 코드의 의도를 명확하게 하고, 다른 개발자도 이해하기 쉽게 작성합니다.
  4. 함수에서 참조 사용 신중히:
    • 함수에 배열을 참조로 전달할 때는, 함수의 목적과 결과를 명확히 문서화하고, 불필요한 참조 사용을 피합니다.
  5. 참조의 범위 제한:
    • 참조는 가능한 한 짧은 범위 내에서 사용하여, 코드의 복잡성을 줄입니다.

8. 실용적인 예제

8.1 배열 참조를 사용한 데이터 필터링

<?php
$numbers = array(1, 2, 3, 4, 5);
$filtered = array();

foreach ($numbers as &$num) {
    if ($num % 2 == 0) {
        $filtered[] = &$num; // 참조로 추가
    }
}
unset($num); // 참조 해제

$filtered[0] = 20;

print_r($numbers); // 출력: Array ( [0] => 1 [1] => 20 [2] => 3 [3] => 4 [4] => 5 )
print_r($filtered); // 출력: Array ( [0] => 20 [1] => 4 )
?>

설명:

  • $filtered 배열은 $numbers 배열의 짝수 요소참조로 저장합니다.
  • $filtered에서 요소를 변경하면, 원본 배열 $numbers에도 변경 사항이 반영됩니다.

8.2 다차원 배열에서 참조를 사용한 값 변경

<?php
$matrix = array(
    array(1, 2, 3),
    array(4, 5, 6),
    array(7, 8, 9)
);

foreach ($matrix as &$row) {
    foreach ($row as &$value) {
        $value += 10;
    }
    unset($value); // 내부 참조 해제
}
unset($row); // 외부 참조 해제

print_r($matrix);
/* 출력:
Array
(
    [0] => Array ( [0] => 11 [1] => 12 [2] => 13 )
    [1] => Array ( [0] => 14 [1] => 15 [2] => 16 )
    [2] => Array ( [0] => 17 [1] => 18 [2] => 19 )
)
*/
?>

설명:

  • 다차원 배열의 각 요소에 참조를 사용하여 값을 직접 변경합니다.
  • unset()을 사용하여 참조를 해제함으로써 의도치 않은 변경을 방지합니다.

9. 결론

PHP 배열 참조는 배열을 효율적으로 관리하고, 여러 변수나 함수에서 동일한 배열을 조작할 때 매우 유용합니다. 그러나 참조를 사용할 때는 참조 해제, 코드의 명확성 유지, 보안 고려 등 주의사항을 철저히 지켜야 합니다. 참조를 적절히 활용하면 메모리 사용 최적화코드의 효율성 향상에 큰 도움이 될 수 있습니다.

주요 포인트 요약:

  • 배열 참조는 배열을 복사하지 않고 원본 배열을 직접 참조합니다.
  • 함수에 배열을 참조로 전달하면 함수 내부에서 배열을 직접 수정할 수 있습니다.
  • foreach 루프에서 참조를 사용할 때는 반드시 참조를 해제하여 의도치 않은 영향을 방지해야 합니다.
  • 배열 참조 사용 시 주의사항을 숙지하고, 최고의 실천 방법을 따르는 것이 중요합니다.

PHP에서 배열 참조를 올바르게 이해하고 사용하면, 더 효율적이고 유지보수가 용이한 코드를 작성할 수 있습니다.


copyright ⓒ 스타트코딩 all rights reserved.
이메일 : startcodingim@gamil.com