php에서 참조를 사용한 코드를 분석 중, 문득 이해가 안가는 문장이 발견 되었습니다.
참조를 처음 접한 건 c++에서 였는데 그 패턴이 익숙한 나머지,
php 참조 문법이 눈에 들어오지 않았던 케이스였습니다.
그래서, php 에서 참조 사용시 주의점을 정리해보려 합니다.
참조를 사용하는 이유 :
•
성능 최적화:
◦
큰 데이터를 복사하지 않고 전달하여 메모리 사용과 처리 속도를 최적화합니다.
•
함수 내 값 변경:
◦
함수 내부에서 전달된 변수의 값을 직접 변경할 수 있습니다.
•
동일 데이터 유지:
◦
여러 변수에서 동일한 데이터를 참조하여 일관성을 유지합니다.
위의 3가지를 대표적인 사용 이유로 볼 수 있으며,
일반적인 예시로 "Call by Reference(참조에 의한 호출)” 가 있습니다.
PHP 참조 사용법 :
php 에서 참조를 사용하는 방법에 대해 간단하게 알아봅시다.
1. 함수 인자 전달
함수 인자로 전달한 원본 변수를 수정할 수 있습니다.
<?php
function increment(&$value) {
$value++;
}
$a = 5;
increment($a);
echo $a; // 출력: 6
?>
PHP
복사
2. 반환 값으로 사용
함수의 반환 값을 참조로 반환할 수 있습니다.
<?php
function &findValue(&$arr, $key) {
return $arr[$key];
}
$arr = ["a" => 1, "b" => 2, "c" => 3];
$value = &findValue($arr, "b");
$value = 4; // $arr["b"]도 4로 변경됩니다.
print_r($arr); // 출력: Array ( [a] => 1 [b] => 4 [c] => 3 )
?>
PHP
복사
3. 배열 요소에 참조 할당
배열의 요소를 참조로 할당할 수 있습니다.
<?php
$arr = [1, 2, 3];
foreach ($arr as &$value) {
$value *= 2;
}
print_r($arr); // 출력: Array ( [0] => 2 [1] => 4 [2] => 6 )
?>
PHP
복사
4. 직접 참조 변수 초기화
<?php
$a = 10;
$b = &$a; // $b는 $a를 참조합니다.
echo "a: $a, b: $b\n"; // a: 10, b: 10
$b = 20; // $b를 변경하면 $a도 변경됩니다.
echo "a: $a, b: $b\n"; // a: 20, b: 20
$c = 30;
$b = &$c; // 이제 $b는 $c를 참조합니다.
$b = 40; // $b를 변경하면 $c도 변경됩니다.
echo "a: $a, b: $b, c: $c\n"; // a: 20, b: 40, c: 40
?>
PHP
복사
여기서 4번 직접 변수를 초기화하는 방법을 살펴봤을 때,
뭔가 틀린게 없는 것 같으면서도, 어색한 부분을 발견할 수 있습니다.
(물론, 위 코드는 단순하기 때문에 발견을 못할 가능성이 큽니다.)
어떤 부분인지 간단하게 적어보자면
1.
참조변수 사용법이 반대 (c++예제 : int &a = b;)
가독성 측면에서 혼동을 줄 수 있으며,
심지어, php 의 함수인자 전달과도 문법이 반대입니다.
포인터와도 유사한 측면이 있어 더욱더 혼동된다고 생각됩니다.
2.
참조변수를 다른 변수로 재할당이 가능 (c++ 불가능)
참조한 변수가 다른 변수로 바뀌는 순간
어떤 값을 참조하고 있는지 혼란이 옵니다.
이 부분은 특히 치명적이라고 생각됩니다.
이 2가지 정도가 코드 가독성을 떨어뜨리는 요인이라고 생각됩니다.
결론적으로 4번의 예제는 함수 인자 전달 방식으로 가독성을 높일 수 있고,
실제로 이런 방식을 권장합니다.
아마, php 언어를 설계한 사람이
c의 포인터를 참고하여 설계를 했는데,
추후 가독성의 문제가 생겨 함수 인자 전달부터는
문법을 고치지 않았을까 하는 조심스러운 추측을 해봅니다.
(개인적 의견입니다.)
결론 :
권장 사항 요약
1.
함수 인자로 참조를 사용할 때: 가독성 유지와 성능 최적화를 위해 적절히 사용합니다.
2.
직접 참조 변수 초기화는 피합니다: 코드의 명확성을 위해 가급적 사용을 자제합니다.
3.
참조 반환은 신중히 사용합니다: 코드의 복잡성을 고려하여 사용합니다.
4.
문서화와 주석을 활용합니다: 참조를 사용하는 부분에 대해 명확히 설명하여 다른 개발자들이 코드를 이해하기 쉽게 만듭니다.
참조 사용에 대한 명확한 기준을 세우고, 가독성과 유지보수성을 고려하여 적절히 사용하면 PHP에서 참조를 효과적으로 활용할 수 있습니다.
참조에 대한 보수적인 측면
c++ 언어에서는 참조 대상을 바꾸는 것도 안되지만,
함수의 매개변수로 전달시 const 를 선언하여, 참조 대상의 값을 수정하는 것도 제한하는 걸 권장합니다.
#include <iostream>
// 함수 정의에서 const를 사용하여 매개변수를 읽기 전용으로 선언
void printValue(const int& value) {
// value = 20; // 컴파일 오류: 읽기 전용 매개변수는 변경할 수 없음
std::cout << "Value: " << value << std::endl;
}
int main() {
int a = 10;
int b = 30;
printValue(a); // a를 참조하여 값을 출력
printValue(b); // b를 참조하여 값을 출력
return 0;
}
C++
복사
이는 포인터와는 다른 용도로 참조를 사용하여, 코드의 안정성과 예측 가능성을 높이며
잘못된 값으로 변경되는 버그를 방지 할 수 있습니다.
이처럼 다른 언어에서도 보수적으로 접근하는 걸 권장하고 있으므로 주의가 필요합니다.
기타
위에서 부정적인 측면을 많이 소개했지만,
php 는 직접 참조를 사용하여 저수준 언어의 문법까지 접근 가능한
좋은 언어임에는 분명하다고 생각합니다.