PHP 변수는 값 또는 참조로 전달됩니까?
PHP 변수는 값 또는 참조로 전달됩니까?
답변:
PHP Documentation 에 따르면 가치가 있습니다.
기본적으로 함수 인수는 값으로 전달됩니다 (따라서 함수 내의 인수 값이 변경되면 함수 외부에서는 변경되지 않습니다). 함수가 인수를 수정할 수있게하려면 참조로 전달해야합니다.
함수에 대한 인수가 항상 참조로 전달되도록 하려면 함수 정의에서 인수 이름 앞에 앰퍼샌드 ( & )를 추가하십시오.
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
$str = add_some_extra($str);
참조를 사용하지 않는 것과 같다 . 그렇다면 그 진정한 부가 가치는 무엇입니까?
$str
에주의하십시오.
PHP에서, 기본적으로 객체는 참조 객체로 새로운 객체에 전달됩니다.
이 예를 참조하십시오 ........
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj->abc = 30;
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 30
이제 이것을보십시오 ..............
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 10 not 20 same as java does.
이제 이것을 참조하십시오 ..............
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue(&$obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 20 not possible in java.
나는 당신이 이것을 이해할 수 있기를 바랍니다.
$y
필요하지 않습니다- function changeValue
안에 있어야 할 것이 class Y
없기 때문에 관련이없는 두 가지 개념이 얽 힙니다. function changeValue
바로 위의 외부 범위 로 이동 합니다 $x = new X();
. 에 대한 모든 참조를 제거하십시오 $y
. 이제 처음 두 예제는 $ x 만 남겨두고 세 번째 예제는 내용을로 변경합니다 new Y()
. 당신이 덤프 있는지 확인하기 쉬울 것 어느 type
의 $x
- 모두 사실 X
과는 Y
포함하는 일이 $abc
필드를 또한 입증 것과 무관
객체가 함수에 전달되는 방식과 참조가 전달하는 방식에 의해 많은 사람들이 혼란스러워하는 것 같습니다. 객체 변수는 여전히 값으로 전달되며, PHP5에서 전달되는 값은 참조 핸들입니다. 증거로 :
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
출력 :
a, b
하기 참조에 의해 전달 수단 우리는 호출자으로 볼 수 있습니다 변수를 수정할 수 있습니다. 위의 코드가 분명히하지 않습니다. 교체 기능을 다음과 같이 변경해야합니다.
<?php
function swap(&$x, &$y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
출력 :
b, a
참조로 전달하기 위해.
swap
함수 에 전달 된 경우와 정확히 일치 합니다. 즉, 객체가 "값에 의해 전달 된"경우. 반면에 객체 핸들이 함수에 전달되면 실제로 예상되는 것과 정확히 일치합니다. 귀하의 코드는이 두 경우를 구별하지 않습니다.
http://www.php.net/manual/en/migration5.oop.php
PHP 5에는 새로운 객체 모델이 있습니다. PHP의 객체 처리가 완전히 다시 작성되어 성능과 기능이 향상되었습니다. 이전 버전의 PHP에서는 객체가 기본 유형 (예 : 정수 및 문자열)과 같이 처리되었습니다. 이 방법의 단점은 전체 객체가 의미 적으로 변수가 할당 될 때 복사되거나 매개 변수로 메서드에 전달되었다는 것입니다. 새로운 접근 방식에서 객체는 값이 아닌 핸들로 참조됩니다 (핸들을 객체의 식별자로 생각할 수 있음).
PHP 변수는 값으로 할당되고, 값으로 함수에 전달되며, 객체를 포함 / 대표하는 경우 참조로 전달됩니다. &를 사용하여 변수를 참조로 전달할 수 있습니다.
값 / 참조 예에 의해 지정 :
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
출력 할 것이다
var1 : 테스트, var2 : 최종 테스트, var3 : 최종 테스트
가치 / 참조 시험에 통과 :
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
출력 :
var1 : foo, var2 바
참조 예를 통해 전달 된 객체 변수 :
class Foo{
public $var1;
function __construct(){
$this->var1 = "foo";
}
public function printFoo(){
print $this->var1;
}
}
$foo = new Foo();
changeFoo($foo);
$foo->printFoo();
function changeFoo($foo){
$foo->var1 = "FOO";
}
출력 :
푸
(마지막 예제는 아마도 더 좋을 것입니다 ...)
$foo
대한 포인터 입니다. $foo
되는 값에 의해 전달 함수에 changeFoo()
로, changeFoo()
과의 매개 변수를 선언하지 않았다 &
.
기본 유형을 포함하는 변수는 PHP5에서 값으로 전달됩니다. 객체를 포함하는 변수는 참조로 전달됩니다. 2006 년 Linux Journal의 흥미로운 기사가 있는데이 기사와 4와 5의 다른 OO 차이점을 언급했습니다.
&
.
객체는 PHP 5에서 참조로, PHP 4에서 값으로 전달됩니다. 변수는 기본적으로 값으로 전달됩니다!
여기를 읽으십시오 : http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
&
.
&
에서 매개 변수 앞에 정의되지 않은 경우에도 함수에 의해 PHP 객체가 수정 될 수 있다고 생각 했습니다. 값으로 전달 된 경우 범위에 포함 된 객체를 매개 변수로 영향을받지 않습니다.
class Holder
{
private $value;
public function __construct( $value )
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
public function setValue( $value )
{
return $this->value = $value;
}
}
class Swap
{
public function SwapObjects( Holder $x, Holder $y )
{
$tmp = $x;
$x = $y;
$y = $tmp;
}
public function SwapValues( Holder $x, Holder $y )
{
$tmp = $x->getValue();
$x->setValue($y->getValue());
$y->setValue($tmp);
}
}
$a1 = new Holder('a');
$b1 = new Holder('b');
$a2 = new Holder('a');
$b2 = new Holder('b');
Swap::SwapValues($a1, $b1);
Swap::SwapObjects($a2, $b2);
echo 'SwapValues: ' . $a2->getValue() . ", " . $b2->getValue() . "<br>";
echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";
참조로 전달되지 않은 경우 속성을 여전히 수정할 수 있으므로주의하십시오.
산출:
스왑 객체 : b, a 스왑 값 : a, b
앞으로이 문제를 겪는 사람이라면 익명의 사용자가 게시 한 PHP 문서 에서이 보석을 공유하고 싶습니다 .
여기에 약간의 혼란이있는 것 같습니다. 포인터와 참조의 구별은 특별히 도움이되지 않습니다. 이미 게시 된 일부 "포괄적 인"예제의 동작은보다 단순한 통일 용어로 설명 할 수 있습니다. 예를 들어, Hayley의 코드는 예상 한대로 정확하게 수행하고 있습니다. (> = 5.3 사용)
첫 번째 원칙 : 포인터는 객체에 액세스하기위한 메모리 주소를 저장합니다. 객체가 할당 될 때마다 포인터가 생성됩니다. (나는 아직 Zend 엔진에 TOO를 깊이 파고 들지 않았지만 볼 수있는 한이 적용됩니다)
두 번째 원칙과 가장 혼란스러운 원인 : 변수에 함수를 전달하는 것은 기본적으로 값 전달로 수행됩니다. 즉, 사본을 사용하는 것입니다. "하지만 객체는 참조로 전달됩니다!" 여기와 자바 세계에서 공통된 오해. 나는 무엇의 사본을 말하지 않았다. 기본 전달은 값으로 수행됩니다. 항상. 그러나 복사되고 전달되는 것은 포인터입니다. "->"를 사용할 때는 물론 호출자 함수의 원래 변수와 동일한 내부에 액세스하게됩니다. "="를 사용하면 사본 만 재생됩니다.
세 번째 원칙 : "&"는 다른 변수 이름 / 포인터를 분리 할 때까지 다른 변수와 동일한 메모리 주소로 자동으로 영구적으로 설정합니다. 여기서 "별칭"이라는 용어를 사용하는 것이 맞습니다. "unset ()"으로 강제 분리 될 때까지 엉덩이에 두 개의 포인터를 연결하는 것으로 생각하십시오. 이 기능은 동일한 범위와 인수가 함수에 전달 될 때 모두 존재합니다. C와 C ++에서 더 명확한 "값으로 전달"과 "참조로 전달"사이의 특정 차이점으로 인해 전달 된 인수를 "참조"라고합니다.
기억하십시오 : 객체 자체가 아닌 객체에 대한 포인터가 함수에 전달됩니다. 이 포인터는 실제로 원본을 전달하기 위해 매개 변수 목록에서 "&"를 사용하지 않는 한 원본의 사본입니다. 개체의 내부를 파헤쳐야만 원본이 변경됩니다.
그리고 그들이 제공하는 예는 다음과 같습니다.
<?php
//The two are meant to be the same
$a = "Clark Kent"; //a==Clark Kent
$b = &$a; //The two will now share the same fate.
$b="Superman"; // $a=="Superman" too.
echo $a;
echo $a="Clark Kent"; // $b=="Clark Kent" too.
unset($b); // $b divorced from $a
$b="Bizarro";
echo $a; // $a=="Clark Kent" still, since $b is a free agent pointer now.
//The two are NOT meant to be the same.
$c="King";
$d="Pretender to the Throne";
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByValue($c, $d);
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByRef($c, $d);
echo $c."\n"; // $c=="Pretender to the Throne"
echo $d."\n"; // $d=="King"
function swapByValue($x, $y){
$temp=$x;
$x=$y;
$y=$temp;
//All this beautiful work will disappear
//because it was done on COPIES of pointers.
//The originals pointers still point as they did.
}
function swapByRef(&$x, &$y){
$temp=$x;
$x=$y;
$y=$temp;
//Note the parameter list: now we switched 'em REAL good.
}
?>
JavaScript에 대한이 주제에 대해 광범위하고 자세한 블로그 게시물을 작성 했지만 PHP, C ++ 및 사람들이 가치에 따라 전달하는 것과 참조로 전달하는 것에 대해 혼란스러워하는 다른 언어에도 똑같이 적용된다고 생각합니다.
분명히 C ++과 같은 PHP는 참조로 전달하는 언어입니다. 기본적으로 객체는 값으로 전달됩니다. 객체를 저장하는 변수로 작업 할 때는 해당 변수를 포인터로 보는 데 도움이됩니다 (조립품 수준에서 기본적으로 변수이기 때문에). 값을 기준으로 포인터를 전달하면 포인터를 "추적"하고 가리키는 객체의 속성을 수정할 수 있습니다. 할 수없는 것은 다른 대상을 가리 키도록하는 것입니다. 참조에 의해 전달 된 것으로 명시 적으로 매개 변수를 선언 한 경우에만이를 수행 할 수 있습니다.
버전에 따라 4는 값 기준이고 5는 참조 기준입니다.