PHP에서 참조가 거의 사용되지 않는 이유는 무엇입니까?


26

C ++에 대한 지식이 있고 거기에서 포인터가 일반적으로 사용된다는 것을 알고 있지만 PHP 오픈 소스 코드를 살펴보기 시작했으며 메서드에서 참조를 사용하는 코드를 보지 못했습니다.

대신 코드는 변수에 대한 참조를 메서드에 전달하는 대신 항상 반환 값을 사용합니다. 그러면 해당 변수의 값이 변경되어 반환됩니다.

참조를 사용하면 적은 메모리를 사용하므로 PHP에서 왜 사용되지 않습니까?


19
참조 별 전달 매개 변수를 사용하는 것은 "부작용 프로그래밍"입니다. 코드를 읽을 때 단일 값을 반환하는 함수를 사용하는 것이 훨씬 더 명확합니다. 즉, 꽤 많은 PHP 핵심 함수가 참조를 사용합니다.
15 분 58 초에

3
PHP는 기본적으로 객체를 참조로 전달합니다.

2
배열 정렬은 참조로 전달되는 핵심 PHP 함수의 주요한 예입니다
Mark Baker

2
PHP 참조는 포인터 가 아니며 , 그들이 어디에 나타나는지를 완전히 기대하지 않으면 종종 엉덩이가 아프다.
lanzz

2
여러 반환해야하는 경우 return array($foo, $bar);list($A, $B) = foobar();
Izkata

답변:


49

참조가 거의 사용되지 않는다는 주장이 잘못되었습니다. 다른 사람들이 이미 언급했듯이 참조를 사용하는 많은 원시 함수가 있지만 주목할만한 예는 배열 정렬 함수preg_match()/ preg_match_all()입니다. 코드에서 이러한 기능을 사용하는 경우 참조도 사용하고 있습니다.

계속해서 PHP의 참조는 포인터 가 아닙니다 . C ++ 배경에서 왔기 때문에 혼란을 이해할 수 있지만 PHP 참조는 완전히 다른 짐승이며 심볼 테이블의 별칭 입니다. C ++ 레퍼런스에서 기대할 수있는 성능 향상은 단순히 PHP 레퍼런스에는 적용되지 않습니다.

실제로, 대부분의 시나리오에서 값으로 전달하는 것은 참조로 전달하는 것보다 빠르고 메모리를 덜 사용합니다. PHP의 핵심 인 젠드 엔진 은 수정 될 때까지 변수의 복사본을 만들지 않는 COW ( Copy-On-Write) 최적화 메커니즘을 사용합니다. 참조로 전달하면 일반적으로 쓰기시 복사 패턴이 깨지고 값을 수정하는지 여부에 관계없이 복사가 필요합니다.

필요할 때 PHP에서 참조를 사용하는 것을 두려워하지 말고 마이크로 최적화하려는 시도로만 사용하지 마십시오. 조기 최적화는 모든 악의 근원이라는 것을 기억하십시오 .

더 읽을 거리 :


@NikiC를 수정 해 주셔서 감사합니다. 게으른 대답 비트이 하나 ...
야 니스

답을 완성하려면 모든 객체가 PHP에서 참조로 전달된다는 것을 지적하는 것이 좋습니다.
Florian Margaine

@FlorianMargaine 완전히 정확하지는 않습니다 (추가 정보는 두 번째 링크 참조).
yannis

2
@FlorianMargaine 아니오, 둘은 매우 다르며 왜 그런지 깨닫는 것이 중요합니다.
phant0m

3
@FlorianMargaine 아니요, PHP에서 객체 참조 전달 되었다고 가정합니다 : f($obj)given function f($x) { $x = new X; }은에 대한 호출 이전과 다른 객체를 $obj참조 했을 것 입니다. 그러나 객체 참조로 전달되지 않으므로 PHP로 이것을 실행하면 $ obj가 수정되지 않습니다. 이런 식으로 PHP는 Java와 동일합니다. f()
phant0m

8

PHP는 이미 값을 변경할 때까지 새로운 값을 생성하지 않는 copy-on-write 작업을 수행하므로 참조를 사용하여 저장되는 메모리가 많지 않습니다. 그렇게하면 내부적으로 메모리 사용량을 줄이기 위해 PHP가 내부적으로하는 일을 망칠 수있어 상황이 더욱 악화됩니다.

덧붙여 참조가 일반적으로 너무 마술 적이라는 사실을 덧붙이십시오. 대부분의 사람들이 기대하는 기본값은 가치에 의한 것입니다. 내가 $i함수에 전달 하면, 그 함수가 $i완전히 다른 것으로 바뀔지 여부를 신경 써야하는 경우를 엄청나게 복잡하게 하고, 만일의 경우를 대비하여 방어적인 사본을 만듭니다. ( $i값이 객체 인 경우 이미 수정할 수 있지만 제 생각에는 그렇지 않아야합니다.)

기본적으로, 난 단지 의미, 내가 기대 변수 통과 참조에 의한 "밖으로"매개 변수에 대한 유용한 찾을 것 돌아가는 기능이 아니라에서 패스 라에서 preg_match의를 &$matches. 또는 처럼 전달되는 객체 를 명확하게 수정하는 함수조차도 약간 불안정한 느낌이지만 ... 우리가 붙어있는 것입니다.sortarray_pop


5

PHP는 웹 지향 언어입니다.
웹 페이지는 빠르게 제공되며 가벼워 야합니다.
일반적인 PHP 프로그램은 몇 초 만에 살고 수백 킬로바이트의 메모리를 소비합니다.
이러한 최적화에는 사용되지 않습니다.


1
이. C ++과 같은 저수준에서 엉망이되지 않으므로 포인터 / 참조가 필요하지 않습니다.
Kenneth Worden

8
이 게시물이 5 이상이되는 이유 a) 질문에 대답하지 않습니다. b) 정확하지 않습니다

1
따라서 참조가 느리고 메모리를 너무 많이 소비합니까?
로켓 Hazmat

1
@RocketHazmat 그렇습니다. 이상하게도 그것은 사실입니다.
yannis

3

몇 가지 이유 :

  • PHP는 스크립팅 언어이며 핵심 임베디드 소프트웨어로 사용되는 것을 목표로하지 않습니다 (기본적으로 스크립트가 끝나면 메모리가 삭제됨).
  • PHP5부터, 참조에 의한 전달은 객체 매개 변수에 대해 암시 적입니다 (따라서 PHP는 "뒤에"에 의한 참조에 의해 전달).

1
두 번째 요점은 php.net/manual/en/language.oop5.references.php 를 참조하십시오 .
yannis

2

나는 이것이 단지 개발자의 선택이며 언어와 관련이 없다고 생각합니다. 많은 PHP 코드 (내장 및 내장되지 않은)는 참조를 사용합니다. PHP의 배열 함수를 살펴보십시오. 많은 함수가 참조를 사용합니다. preg_match참조를 사용합니다.

개발자가 참조를 사용하지 않기로 선택한 이유 중 하나는 혼란 스러울 수 있기 때문이라고 생각합니다. 함수를 호출하면 변수 중 하나가 참조이므로 업데이트되거나 업데이트되지 않을 수 있습니다. 따라서 디버깅 할 때 $xjsut 의 값이 마술처럼 변경된 이유가 명확하지 않을 수 있습니다 .


1

질문의 근본적인 문제는 이것이 C ++에서도 공통적이라고 가정한다는 것입니다. 그렇지 않습니다. 우리는 출력 매개 변수를 좋아하지 않고 가능한 한 적게 사용합니다. C 스타일 API에서만 실제로 사용됩니다.


0

나는 그렇게하는 많은 PHP 기능을 알고 있습니다. 한 번 봐 가지고 preg_match()예를 들어. $matches참조로 전달됩니다

참조로 인수를 취하는 함수를 직접 작성하려면 다음 구문을 사용하십시오.

function byref(&$a, &$b, $c) {
    $a += $c;
    $b += $c;
    return $a * $b;
}

$ a 및 $ b는 참조로 전달됩니다. $ c는 값으로 전달됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.