PHP의 배열이 값 또는 참조로 전달됩니까?
PHPPHP의 배열이 값 또는 참조로 전달됩니까?
배열이 메서드 또는 함수에 인수로 전달되면 참조로 전달됩니까?
이 일을하는 것은 어떨까요?
$a = array(1,2,3);
$b = $a;
$ b는 $ a에 대한 참조입니까?
해결법
-
==============================
1.질문의 두 번째 부분은 설명서의 배열 페이지를 참조하십시오.
질문의 두 번째 부분은 설명서의 배열 페이지를 참조하십시오.
그리고 주어진 예제 :
<?php $arr1 = array(2, 3); $arr2 = $arr1; $arr2[] = 4; // $arr2 is changed, // $arr1 is still array(2, 3) $arr3 = &$arr1; $arr3[] = 4; // now $arr1 and $arr3 are the same ?>
첫 번째 부분에서는 반드시 시도하는 것이 가장 좋은 방법입니다 ;-)
다음 코드 예제를 고려하십시오.
function my_func($a) { $a[] = 30; } $arr = array(10, 20); my_func($arr); var_dump($arr);
이 결과는 다음과 같습니다.
array 0 => int 10 1 => int 20
어떤 함수가 매개 변수로 전달 된 "외부"배열을 수정하지 않았 음을 나타냅니다. 참조가 아닌 복사본으로 전달됩니다.
참조로 전달하려면 다음과 같이 함수를 수정해야합니다.
function my_func(& $a) { $a[] = 30; }
출력은 다음과 같이됩니다.
array 0 => int 10 1 => int 20 2 => int 30
이번에는 배열이 "참조로"전달되었습니다.
설명서의 References Explained 섹션을 주저하지 말고 질문에 대한 답을해야합니다.
-
==============================
2.귀하의 첫 번째 질문에 관해서는 배열은 당신이 호출하는 메서드 / 함수 내에서 수정되지 않는 한 참조로 전달됩니다. 메서드 / 함수 내에서 배열을 수정하려고하면 먼저 메서드의 복사본이 만들어지고 복사본 만 수정됩니다. 이것은 실제로 배열이 값으로 전달 된 것처럼 보이게합니다.
귀하의 첫 번째 질문에 관해서는 배열은 당신이 호출하는 메서드 / 함수 내에서 수정되지 않는 한 참조로 전달됩니다. 메서드 / 함수 내에서 배열을 수정하려고하면 먼저 메서드의 복사본이 만들어지고 복사본 만 수정됩니다. 이것은 실제로 배열이 값으로 전달 된 것처럼 보이게합니다.
예를 들어,이 첫 번째 경우에 매개 변수 정의에서 & 문자를 사용하여 $ my_array를 참조로 받아들이도록 함수를 정의하지 않더라도 참조로 전달됩니다 (예 : 메모리를 낭비하지 않음). 불필요한 사본으로).
function handle_array($my_array) { // ... read from but do not modify $my_array print_r($my_array); // ... $my_array effectively passed by reference since no copy is made }
그러나 배열을 수정하면 먼저 복사본이 만들어지고 (더 많은 메모리를 사용하지만 원래 배열은 영향을받지 않습니다).
function handle_array($my_array) { // ... modify $my_array $my_array[] = "New value"; // ... $my_array effectively passed by value since requires local copy }
참고 - 이것을 "lazy copy"또는 "copy-on-write"라고합니다.
-
==============================
3.a) 메서드 / 함수는 배열 인자 => 암시 적 (내부) 참조 만 읽는다. b) 메서드 / 함수가 배열 인수 => 값을 수정합니다. c) 메소드 / 함수 배열 인수는 명시 적으로 참조 (앰퍼샌드 포함) => 명시 적 (사용자 - 랜드) 참조로 표시됩니다.
a) 메서드 / 함수는 배열 인자 => 암시 적 (내부) 참조 만 읽는다. b) 메서드 / 함수가 배열 인수 => 값을 수정합니다. c) 메소드 / 함수 배열 인수는 명시 적으로 참조 (앰퍼샌드 포함) => 명시 적 (사용자 - 랜드) 참조로 표시됩니다.
아니면 이거: - 앰퍼샌드가 아닌 배열 매개 변수 : 참조로 전달됩니다. 기입 조작에 의해, 배열의 새로운 카피가 변경됩니다. 카피는 최초의 기입 해에 작성됩니다. - 앰퍼샌드 배열 매개 변수 : 참조로 전달됩니다. 기입 조작에 의해, 원의 배열이 변경됩니다.
기억하십시오 - PHP는 앰퍼샌드가 아닌 배열 매개 변수에 쓸 순간에 값 복사를 수행합니다. 이것이 바로 복사 중 복사의 의미입니다. 나는이 행동의 C 소스를 보여주고 싶지만 그곳에는 무서운 것이있다. xdebug_debug_zval ()을 더 잘 사용하십시오.
파스칼 마틴이 옳았다. Kosta Kontos는 훨씬 그렇습니다.
그것은 달려있다.
나는 내 자신을 위해 이것을 쓰고 있다고 생각한다. 나는 블로그 또는 뭔가를 가져야한다. ..
사람들이 참조 (또는 포인터)에 관해 이야기 할 때마다, 그들은 대개 logomachy로 끝납니다 (이 스레드를보세요). PHP는 유서 깊은 언어이기 때문에, (비록 위의 답변을 요약해도) 혼란에 빠뜨릴 것이라고 생각했습니다. 왜냐하면 두 사람이 동시에 맞을지라도 머리를 하나의 답으로 분해하는 것이 낫습니다.
먼저, 흑백 방식으로 대답하지 않으면 당신이 보잘것 없다는 것을 알아야합니다. 상황은 "예 / 아니오"보다 복잡합니다.
보시다시피, 전체 by-value / by-reference는 메서드 / 함수 범위에서 정확히 배열과 관련된 작업과 매우 관련이 있습니다 : 읽기 또는 수정?
설명서에 다음과 같이 쓰여 있습니다 (강조).
내가 말할 수있는 한 크고 진지하고 정직한 신 프로그래머가 참조에 관해 말할 때 대개 그 참조의 가치를 바꾸는 것에 대해 이야기합니다. 그리고 그것은 매뉴얼에서 말한 것과 정확히 같습니다. 함수에서 값을 변경하려면 PHP가 "값별로 전달"을 수행하는 것으로 간주하십시오.
그들이 언급하지 않은 또 다른 사례가 있습니다. 내가 무엇인가를 바꾸지 않으면 어떻게 읽습니까? 명시 적으로 참조를 표시하지 않는 메서드에 배열을 전달하고 함수 범위에서 해당 배열을 변경하지 않으면 어떻게됩니까? 일명 :
<?php function printArray($array) {} $x = array(1); printArray($x);
읽기, 내 동료 여행자.
똑같은 크고 진지한 프로그래머들이 더 심각 해지면 참조와 관련하여 "메모리 최적화"에 대해 이야기합니다. PHP도 그렇습니다. PHP는 동적으로 느슨하게 형식화 된 언어이므로 쓰기시 복사 및 참조 계산을 사용하므로 그 이유가 있습니다.
커다란 배열을 다양한 함수에 전달하는 것은 이상적이지 않으며, PHP는 그것들의 복사본을 만들어내는 것이 이상적이지 않을 것입니다 (결국 "pass-by-value"가하는 것입니다).
<?php // filling an array with 10000 elements of int 1 // let's say it grabs 3 mb from you RAM $x = array_fill(0, 10000, 1); // pass by value, right? RIGHT? function readArray($arr) { // <-- a new symbol (variable) gets created here echo count($arr); // let's just read the array } readArray($x);
자, 실제로이 값이 패스라면, 그 배열의 복사본이 2 개 있기 때문에 3MB + RAM이 사라질 것입니다. 맞습니까?
잘못된. 우리가 $ arr 변수를 변경하지 않는 한 그것은 메모리에 대한 참조입니다. 너는 단지 그것을 보지 못한다. 이것이 PHP가 내부와 명시 적 (앰퍼샌드 포함)을 구별하기 위해 & someVar에 대해 이야기 할 때 사용자 영역 참조를 언급하는 이유입니다.
따라서 배열이 메서드 나 함수에 인수로 전달되면 참조로 전달됩니까?
나는 세 가지 (예, 세 가지)의 경우를 생각해 냈습니다. a) 메서드 / 함수는 배열 인수 만 읽습니다. b) 메서드 / 함수가 배열 인수를 수정합니다. c) 메소드 / 함수 배열 인수는 명시 적으로 참조로 표시됩니다 (앰퍼샌드 포함)
우선 배열이 실제로 먹는 메모리 양을 봅시다 (여기에서 실행하십시오) :
<?php $start_memory = memory_get_usage(); $x = array_fill(0, 10000, 1); echo memory_get_usage() - $start_memory; // 1331840
그 많은 바이트. 큰.
이제는 해당 배열을 인수로만 읽는 함수를 만들고 읽기 논리에 필요한 메모리 양을 봅시다.
<?php function printUsedMemory($arr) { $start_memory = memory_get_usage(); count($arr); // read $x = $arr[0]; // read (+ minor assignment) $arr[0] - $arr[1]; // read echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading } $x = array_fill(0, 10000, 1); // this is 1331840 bytes printUsedMemory($x);
맞춰 볼래? 나는 80을 얻는다! 직접보십시오. 이것은 PHP 매뉴얼에서 생략 한 부분입니다. $ arr 매개 변수가 실제로 전달 된 값은 1331840 바이트와 비슷합니다. $ arr이 참조처럼 작동하는 것 같지 않습니까? 내부 참조가 참조이기 때문입니다.
이제 param에서 읽는 대신에 param에 쓰자.
<?php function printUsedMemory($arr) { $start_memory = memory_get_usage(); $arr[0] = 1; // WRITE! echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading } $x = array_fill(0, 10000, 1); printUsedMemory($x);
다시 말하지만, 직접 보아라.하지만 나에게는 1331840에 가깝다.이 경우 배열은 실제로 $ arr에 복사 중이다.
이제 명시 적 참조에 대한 쓰기 작업이 얼마나 많은 메모리를 사용하는지 살펴 보겠습니다 (여기에서 실행) - 함수 서명의 앰퍼샌드를 확인하십시오.
<?php function printUsedMemory(&$arr) // <----- explicit, user-land, pass-by-reference { $start_memory = memory_get_usage(); $arr[0] = 1; // WRITE! echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading } $x = array_fill(0, 10000, 1); printUsedMemory($x);
제 내기는 당신이 200 점을 얻는 것입니다! 따라서 앰퍼샌드가 아닌 매개 변수에서 읽는 것만큼 메모리를 많이 사용합니다.
-
==============================
4.기본적으로
기본적으로
참고 : 최적화로 모든 단일 값은 함수 내부에서 수정 될 때까지 참조로 전달됩니다. 수정 된 값이 참조에 의해 전달되면 값이 복사되고 사본이 수정됩니다.
-
==============================
5.PHP에서 배열이 메서드 나 함수에 전달되면 명시 적으로 참조로 전달하지 않으면 값에 의해 전달됩니다. 예 :
PHP에서 배열이 메서드 나 함수에 전달되면 명시 적으로 참조로 전달하지 않으면 값에 의해 전달됩니다. 예 :
function test(&$array) { $array['new'] = 'hey'; } $a = $array(1,2,3); // prints [0=>1,1=>2,2=>3] var_dump($a); test($a); // prints [0=>1,1=>2,2=>3,'new'=>'hey'] var_dump($a);
두 번째 질문에서 $ b는 $ a에 대한 참조가 아니고 $ a의 복사본입니다.
첫 번째 예제와 비슷하게 다음을 수행하여 $ a를 참조 할 수 있습니다.
$a = array(1,2,3); $b = &$a; // prints [0=>1,1=>2,2=>3] var_dump($b); $b['new'] = 'hey'; // prints [0=>1,1=>2,2=>3,'new'=>'hey'] var_dump($a);
-
==============================
6.이 스레드는 약간 나이가 들었지만, 여기에 나온 것은 뭔가 있습니다 :
이 스레드는 약간 나이가 들었지만, 여기에 나온 것은 뭔가 있습니다 :
이 코드를보십시오 :
$date = new DateTime(); $arr = ['date' => $date]; echo $date->format('Ymd') . '<br>'; mytest($arr); echo $date->format('Ymd') . '<br>'; function mytest($params = []) { if (isset($params['date'])) { $params['date']->add(new DateInterval('P1D')); } }
http://codepad.viper-7.com/gwPYMw
$ params 매개 변수에 대한 앰프가 없으며 $ arr [ 'date']의 값을 변경합니다. 이것은 여기에있는 다른 모든 설명들과 지금까지 생각했던 것과 실제로 일치하지 않습니다.
$ params [ 'date'] 객체를 복제하면 두 번째로 출력 된 날짜가 그대로 유지됩니다. 방금 문자열로 설정하면 출력에도 영향을주지 않습니다.
-
==============================
7.PHP에서는 배열이 명시 적으로 참조로 전달되지 않는 한 기본적으로 값에 의해 함수에 전달됩니다. 다음 스 니펫이 보여줍니다.
PHP에서는 배열이 명시 적으로 참조로 전달되지 않는 한 기본적으로 값에 의해 함수에 전달됩니다. 다음 스 니펫이 보여줍니다.
$foo = array(11, 22, 33); function hello($fooarg) { $fooarg[0] = 99; } function world(&$fooarg) { $fooarg[0] = 66; } hello($foo); var_dump($foo); // (original array not modified) array passed-by-value world($foo); var_dump($foo); // (original array modified) array passed-by-reference
출력은 다음과 같습니다.
array(3) { [0]=> int(11) [1]=> int(22) [2]=> int(33) } array(3) { [0]=> int(66) [1]=> int(22) [2]=> int(33) }
from https://stackoverflow.com/questions/2030906/are-arrays-in-php-passed-by-value-or-by-reference by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
SUDO가 필요한 PHP에서 쉘 스크립트를 호출하는 방법은 무엇입니까? (0) | 2018.09.19 |
---|---|
MySQL, MySQLi 및 PDO의 차이점은 무엇입니까? [닫은] (0) | 2018.09.19 |
PHP : $ _SESSION 안에 '객체'저장하기 (0) | 2018.09.19 |
PHP cURL 사용자 정의 헤더 (0) | 2018.09.19 |
컬에 JSON을 PHP로 게시하는 방법 (0) | 2018.09.19 |